强制编译器选择以 const T& 作为参数的复制构造函数
Force compiler to choose copy constructor with const T& as a parameter
我正在写一个类,我有一个模板化的构造函数和复制构造函数。每次我想用非const对象调用复制构造函数时,都会选择模板化构造函数。如何强制编译器选择复制构造函数?
#include <iostream>
struct foo
{
foo()
{
std::cout << "def constructor is invokedn";
}
foo(const foo& other)
{
std::cout << "copy constructor is invokedn";
}
template <typename T>
foo(T&& value)
{
std::cout << "templated constructor is invokedn";
}
};
int main()
{
foo first;
foo second(first);
}
删除函数不是我想要的。
添加另一个构造函数:
foo(foo& other) : foo( const_cast<const foo&>(other)) // for non-const lvalues
{
}
示例代码中的first
对象是非const左值,因此编译器更喜欢foo(foo&)
而不是foo(const &)
。前者由模板(含T=foo&
)提供,因此选择
这个解决方案包括为foo(foo&)
提供一个(非模板)构造函数,然后通过将其强制转换为对const的引用来将构造委托给复制构造函数。
更新,我刚刚意识到foo
右值也将被模板采用。这里有很多选项,但我想最简单的是为foo(foo&&)
添加一个委托,类似于上面的
foo(foo&& other) : foo( const_cast<const foo&>(other)) // for rvalues
{
}
问题是first
是可变的,所以对它的引用是一个foo&
,它比const foo&
更容易绑定到通用引用T&&
。
大概,你打算T
是任何非foo类?
在这种情况下,少量的enable_if
欺骗向编译器表达了意图,而不必编写虚假的重载加载。
#include <iostream>
struct foo
{
foo()
{
std::cout << "def constructor is invokedn";
}
foo(const foo& other)
{
std::cout << "copy constructor is invokedn";
}
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 invokedn";
}
};
int main()
{
foo first;
foo second(first);
foo(6);
}
预期输出:def constructor is invoked
copy constructor is invoked
templated constructor is invoked
相关文章:
- C++:使用运算符 = 调用多参数构造函数
- 通过零参数构造函数创建的 glm::mat4 应该包含哪些值?
- 好奇的混合与可变参数构造函数
- 具有默认值的单个参数构造函数是否与默认构造函数相同?
- 为什么我们需要创建一个单参数构造函数来使用临时的无名称对象
- 在可变参数构造函数中初始化常量数组
- C++ 显式多参数构造函数歧义
- 零一参数构造函数
- 可变参数构造函数中的 SFINAE
- 当没有显式关键字与单参数构造函数一起使用时,编译器可以发出警告
- 可变参数类模板和可变参数构造函数
- 确保模板参数类型与其可变参数构造函数的类型匹配
- C++默认参数构造函数与内联初始化优先级
- 如何在 c++ 中将包含复制构造函数的类的参数构造函数称为私有?
- 自动存储中没有无参数构造函数的类对象和异常
- 警告:用两个参数构造函数返回对象时,表达结果未使用
- 如何在C++中调用无参数构造函数
- 在 c++ 中具有多个参数构造函数的模板类存在问题
- 可变参数构造函数优先于用户提供的移动构造函数,除非默认
- 如何从可变参数构造函数参数构造任何对象?