EffectiveModernC++说调用模板构造函数,而不是调用默认构造函数
Person p("Nancy");
auto cloneOfP(p); 对于类:
class Person {
public:
template<typename T> // perfect forwarding ctor
explicit Person(T&& n)
: name(std::forward<T>(n)) {}
explicit Person(int idx); // int ctor
Person(const Person& rhs); // copy ctor
// (compiler-generated)
Person(Person&& rhs); // move ctor
… // (compiler-generated)
};我理解p的const的缺失使模板成为一个更好的候选者。但我不明白为什么我们不想要这个?
我们不是总想调用模板版本吗,因为它会转发(rvalue、ref或lvalue)。
换句话说,我们希望触发默认(生成的)构造函数的情况是什么?
发布于 2020-03-12 08:01:07
但是我不明白为什么我们不想要这个
?
因为它会使代码无法编译。如果我们用下面的语句完成这个示例
class Person {
public:
template<typename T> // perfect forwarding ctor
explicit Person(T&& n)
: name(std::forward<T>(n)) {}
explicit Person(int idx); // int ctor
Person(const Person& rhs); // copy ctor
// (compiler-generated)
Person(Person&& rhs); // move ctor
std::string name; // (compiler-generated)
};
int main()
{
Person p("Nancy");
auto cloneOfP(p);
}我们收到编译器错误,如下所示
main.cpp: In instantiation of 'Person::Person(T&&) [with T = Person&]':
main.cpp:28:20: required from here
main.cpp:14:30: error: no matching function for call to 'std::__cxx11::basic_string<char>::basic_string(Person&)'
14 | : name(std::forward<T>(n)) {}这就是为什么像这样的模板是一件坏事。当T是类类型时,它需要使用SFINAE来阻止它被调用。这看起来就像
class Person {
public:
template<typename T, std::enable_if_t<!std::is_same_v<std::decay_t<T>, Person>, bool> = true> // perfect forwarding ctor
explicit Person(T&& n)
: name(std::forward<T>(n)) {}
explicit Person(int idx); // int ctor
Person(const Person& rhs); // copy ctor
// (compiler-generated)
Person(Person&& rhs); // move ctor
std::string name; // (compiler-generated)
};https://stackoverflow.com/questions/60645868
复制相似问题