问题描述
我正在编写一个具有模板化构造函数和复制构造函数的类。每次我想用非const对象调用复制构造函数时,都会选择模板化构造函数。如何强制编译器选择复制构造函数?
I'm writing a class where I have a templated constructor and copy constructor. Every time I want to call copy constructor with non const object, templated constructor gets chosen. How can I force compiler to choose copy constructor?
这是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);
}
删除功能不是我想要的。
Deleting a function is not what I want.
推荐答案
问题是 first
是可变的,因此对其的引用是 foo&
比 const foo& $ c更容易绑定到通用引用
T&
$ c>。
The problem is that first
is mutable, so a reference to it is a foo&
which binds to the universal reference T&&
more readily than const foo&
.
想必您打算 T
是任何非foo类吗?
Presumably, you intended that T
was any non-foo class?
在这种情况下, enable_if
一点点地表达了编译器的意图,而不必编写大量的伪重载。
In which case a little bit of enable_if
chicanery expresses intent to the compiler without having to write a load of spurious overloads.
#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);
}
预期产量:
def constructor is invoked
copy constructor is invoked
templated constructor is invoked
这篇关于强制编译器选择带有const T&的复制构造函数作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!