我有以下代码:
#include <iostream>
#include <typeinfo>
template <typename T>
struct A : T {
template <typename ...Args>
A(Args&&... params) : T(std::forward<Args>(params)...), x(0) {
std::cout << "Member 'x' was default constructed\n";
}
template <typename O, typename ...Args, typename = typename std::enable_if<std::is_constructible<int,O>::value>::type>
A(O o, Args&&... params) : T(std::forward<Args>(params)...), x(o) {
std::cout << "Member 'x' was constructed from arguments\n";
}
int x;
};
struct B{
B(const char*) {}
};
int main() {
A<B> a("test");
A<B> y(3, "test");
return 0;
}
它工作正常,并打印
Member 'x' was default constructed
Member 'x' was constructed from arguments
但是,如果第二个重载的第一个参数是一个引用,那么突然第二个重载就不会被采用,并且编译会失败:
template <typename O, typename ...Args, typename = typename std::enable_if<std::is_constructible<int,O>::value>::type>
A(O& o, Args&&... params) : T(std::forward<Args>(params)...), x(o) {
std::cout << "Member 'x' was constructed from arguments\n";
} // Note the O& in the arguments
为什么是这样?是否可以修复它并避免复制?
编辑:使用通用参考显然使它再次工作。一个const
参考,这是我真正想要的,也不起作用。
此外,即使将输入参数保存为单独的值(避免右值)仍然不起作用:
int main() {
double x = 3.0;
A<B> y(x, "test"); // Still not working
return 0;
}