template<typename T>
class SharedValue {
public:
SharedValue(const T& t): valuePtr(new T(t)) {}
const SharedValue& operator = (const T &t) {
*valuePtr = t;
return *this;
}
protected:
dd_shared_ptr<T> valuePtr;
};
typedef SharedValue<std::string> SharedString;
int main(int argc, const char * argv[]) {
// compile succeeded
SharedString str(argv[0]);
// compile failed:
SharedString str2 = argv[0];
return 0;
}
The str2
construction failed, reporting:
No viable conversion from 'const char *' to 'SharedString' (aka 'SharedValue<basic_string<char, char_traits<char>, allocator<char>>>')
Why str
succeeded whereas str2
failed, is there any difference?
CodePudding user response:
Why str succeeded whereas str2 failed, is there any difference?
Yes, there is difference between the two. In particular, in str
we have have direct initialization while in str2
we have copy initialization.
The behavior of your program can be understood from copy initialization documentation which states:
In addition, the implicit conversion in copy-initialization must produce
T
directly from the initializer, while, e.g. direct-initialization expects an implicit conversion from the initializer to an argument ofT
's constructor.
(emphasis mine)
Now let's apply this to your given example on case by case basis.
Case 1
Here we consider the statement:
SharedString str2 = argv[0]; //this is copy initialization
The above uses copy initialization. And as SharedString
can't be directly produced from the initializer of type const char*
on the right hand side since it requires an implicit conversion, this case 1 isn't allowed in accordance with the above quoted statement.
Case 2
Here we consider the statement:
SharedString str(argv[0]); //this is direct initialization
while the above uses direct initialization and since there is an implicit conversion available(using the converting constructor), this time it is allowed according to the above quoted statement.