Why are templated copy constructors ignored? [duplicate] - c++

This question already has answers here:
Copy constructor of template class
(2 answers)
Why can't I override the default copy constructor and assignment operator with template versions in C++
(2 answers)
Closed 4 years ago.
I think this code should print "hit" but it doesn't. If you comment out line 6 (the template line), it prints "hit."
#include <iostream>
struct test {
test() {}
template<typename = typename std::enable_if<true>::type>
test(test const & other) {
std::cout << "hit";
}
};
int main()
{
test a;
test b(a);
}
The standard explicitly indicates this. What's the rationale?

Related

C++ constructor invocation [duplicate]

This question already has answers here:
How does guaranteed copy elision work?
(2 answers)
What are copy elision and return value optimization?
(5 answers)
Closed 21 days ago.
The following invokes one instance of the constructor followed by the destructor of A (vs. invoking copy or move constructors). Is this an optimization that only one instance of A is created, or is this behavior mandated by the standard?
#include <iostream>
struct A {
A() {
std::cout << "Constructor\n";
}
~A() {
std::cout << "Destructor\n";
}
A (const A&) = delete;
};
int main() {
A a{A{A{A{A{}}}}};
}

When exactly is copy constructor called? [duplicate]

This question already has answers here:
c++: MyClass x(1,2,3) vs MyClass x = MyClass(1,2,3)
(1 answer)
What's the difference between Radio r = Radio("PSR", 100.8) and Radio("PSR", 100.8)?
(1 answer)
Shouldn't there be a copy ctor invocation here? Elision disabled (no named return value optimization)
(1 answer)
Copy/Move Constructor is not called when storing result of overloaded operator+
(1 answer)
Closed 7 months ago.
I have the following code:
#include<iostream>
using namespace std;
class A{
private:
int x;
public:
A(){x=10;}
A(int m){x=m; cout << "int m constructor" << m << endl;}
A(A& a){cout << "copy constructor:"<<a.x<<"\n"; x=a.x;}
A(A&& a){cout <<"move constructor:"<<a.x<<"\n"; x=a.x;}
};
int main(){
A a(100);
A b = a;
A d = A(30);
}
which outputs the following:
int m constructor100
copy constructor:100
int m constructor30
I was expecting it to output
int m constructor100
copy constructor:100
copy constructor:30
because the constructor function (A(30)) is called.
But somehow the compiler optimises it?
Also A d = A(A(30)) also prints int m constructor30.
Is there some compiler optimization happening here?
Your last line A d = A(30) and A d = A(A(30)) is the mandatory copy elision.

Replacing Implicitly-Deleted Operator With Template Method [duplicate]

This question already has answers here:
Template assignment operator doesn't replace the default assignment operator
(2 answers)
Template assignment operator overloading mystery
(2 answers)
Closed 4 years ago.
Consider the following code:
class Foo { public:
int const i;
Foo() : i(0) {}
};
void test() {
Foo a;
Foo const b;
a = b; //Failure here; `Foo::operator=` implicitly deleted
}
The indicated line fails because the operator= ordinarily generated by the compiler cannot be generated: .i is marked const. This is good and expected.
The programmer can generate their own operator=, so long as it does not change .i. E.g. this method does nothing:
Foo& operator=(Foo const& other) {
return *this;
}
But now, suppose I want to be more-general. I templatize the method:
template <typename TypeOther>
Foo& operator=(TypeOther const& other) {
return *this;
}
Suddenly, I get back the original failing behavior (tested Clang, GCC, and MSVC)! It seems that, even though the default operator= is not generated, it participates in overload resolution and therefore is selected instead of the template variant.
Why is the implicit operator is being selected even though it does not exist (i.e, is it as if I had just written and deleted it myself—that is, it exists but is forbidden)?
How I can work around this to make my template operator= be selected for any type?

C++ - Unable to overload assignment operator [duplicate]

This question already has answers here:
The assignment operator and initialization
(2 answers)
Closed 6 years ago.
I am trying to overload the assignment operator but it doesn't seem to work. The code is based on this answer. I've searched for other examples of overloading the assignment operator, but it doesn't seem like my code shouldn't run.
This is my code:
#pragma once
#include <assert.h>
class ReadOnlyInt
{
public:
ReadOnlyInt(): assigned(false) {}
ReadOnlyInt& operator=(int v);
operator int() const ;
private:
int value;
bool assigned;
};
ReadOnlyInt& ReadOnlyInt::operator=(int v)
{
assert(!assigned);
value = v;
assigned = true;
return *this;
}
ReadOnlyInt::operator int() const
{
assert(assigned);
return value;
}
Intellisense doesn't give any warnings, but the operator= is not highlighted as a keyword.
Now if I make an assigment, Intellisense does recognize it's not possible:
ReadOnlyInt bar = 12;
no suitable constructor exists to convert from "int" to "ReadOnlyInt"
This works however:
int foo = bar;
Solution
This question was marked as duplicate, so I can't answer it. This was the solution I came up with based on the comments and answer on this question:
ReadOnlyInt::ReadOnlyInt()
: assigned(false)
{}
ReadOnlyInt::ReadOnlyInt(int v)
: value(v), assigned(true)
{}
You can't initialize and declare at the same time. You need to do this
ReadOnlyInt bar;
bar = 12;
This is because there is no appropriate constructor for ReadOnlyInt that takes an int argument.

What is wrong in this C++ code? Compile error: no matching function for call to ‘Test::Test(Test)’ [duplicate]

This question already has answers here:
Why is the copy-constructor argument const?
(8 answers)
Closed 9 years ago.
#include<iostream>
using namespace std;
class Test
{
/* Class data members */
public:
Test(Test &t) { /* Copy data members from t*/}
Test() { /* Initialize data members */ }
};
Test fun()
{
cout << "fun() Called\n";
Test t;
return t;
}
int main()
{
Test t1;
Test t2 = fun();
return 0;
}
What is wrong with above C++ code? compiler throws following error.
error: no matching function for call to ‘Test::Test(Test)’
You declared a copy constructor which requires a non-const lvalue. However, fun() returns a temporary and you can't bind a temporary to a non-const lvalue. You probably want to declare your copy constructor as
Test(Test const& t) { ... }