【发布时间】:2014-09-23 17:30:12
【问题描述】:
我有以下代码:
#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;
}
【问题讨论】:
标签: c++ c++11 overloading variadic-templates universal-reference