Inc*_*ble 6 c++ copy-constructor c++14
我正在写一个类,我有一个模板化的构造函数和复制构造函数.每次我想用非const对象调用复制构造函数时,都会选择模板化构造函数.如何强制编译器选择复制构造函数?
这是mcve:
#include <iostream>
struct foo
{
foo()
{
std::cout << "def constructor is invoked\n";
}
foo(const foo& other)
{
std::cout << "copy constructor is invoked\n";
}
template <typename T>
foo(T&& value)
{
std::cout << "templated constructor is invoked\n";
}
};
int main()
{
foo first;
foo second(first);
}
Run Code Online (Sandbox Code Playgroud)
删除功能不是我想要的.
添加另一个构造函数:
foo(foo& other) : foo( const_cast<const foo&>(other)) // for non-const lvalues
{
}
Run Code Online (Sandbox Code Playgroud)
的first在您的示例代码对象是一个非const左值,因此编译器倾向于foo(foo&)过度foo(const &).前者由模板(with T=foo&)提供,因此被选中.
这个解决方案涉及提供一个(非模板)构造函数foo(foo&),然后通过将构造函数转换为const-to-const来将构造委托给复制构造函数.
更新,我刚刚意识到foo模板也将采用右值.这里有很多选项,但我想最简单的方法是添加一个委托foo(foo&&),类似于上面的一个
foo(foo&& other) : foo( const_cast<const foo&>(other)) // for rvalues
{
}
Run Code Online (Sandbox Code Playgroud)
问题是它first是可变的,因此对它foo&的引用T&&更容易与通用引用结合const foo&.
据推测,你打算T做任何非foo课程吗?
在这种情况下,一点点的enable_ifchicanry表达了对编译器的意图,而不必编写一系列虚假的重载.
#include <iostream>
struct foo
{
foo()
{
std::cout << "def constructor is invoked\n";
}
foo(const foo& other)
{
std::cout << "copy constructor is invoked\n";
}
template <typename T, std::enable_if_t<not std::is_base_of<foo, std::decay_t<T>>::value>* = nullptr>
foo(T&& value)
{
std::cout << "templated constructor is invoked\n";
}
};
int main()
{
foo first;
foo second(first);
foo(6);
}
Run Code Online (Sandbox Code Playgroud)
预期产量:
def constructor is invoked
copy constructor is invoked
templated constructor is invoked
Run Code Online (Sandbox Code Playgroud)