我正在尝试创建一个类,它应该从其他类继承构造函数,但不从这些类本身继承。
在我的类初始化期间,我想使用完美转发来创建一个类型的对象,其构造函数与给定的参数匹配。
除了没有参数的默认构造函数外,不存在歧义。
这是我的代码:
#include <string>
using namespace std;
//NOTE: this class is just an example to demonstrate the problem
class String {
public:
//default constructor to prevent ambiguity
String() {}
//construct from wstring
template<typename... Args>
String(enable_if<is_constructible<wstring, Args...>::value, Args>::type&&... args) : ws(forward<Args>(args)...) {}
//construct from string
template<typename... Args>
String(enable_if<is_constructible<string, Args...>::value, Args>::type&&... args) : s(forward<Args>(args)...) {}
private:
string s;
wstring ws;
};
void foo(const String& string) {
}
int main()
{
foo(L"123");
foo("123");
return 0;
}
我尝试了很多东西,但我无法让它发挥作用。
enable_if
无法自动扣除模板参数(我认为)enable_if
enable_if
添加另一个默认参数将不起作用,因为构造函数是variadic enable_if
时,编译器会抱怨无效的重载(当然)有没有一种优雅的方法来解决这个问题?
编辑: 标准允许的一个隐式转换不应该出现在我的班级中。 [示例代码编辑]
与上述示例一起使用的一个解决方案是定义单个可变参数构造函数,并将参数完美地转发到条件初始化函数。但是,我想避免这种开销,因为成员需要默认构造,这在其他情况下可能不起作用。
(如果事情可以更清楚,请随意编辑问题)
答案 0 :(得分:2)
我无法理解问题以及解决方案。如果我想为方法或构造函数使用2种不同的类型,我可以简单地编写这两种类型。因此,没有必要有SFINAE的模板!这可以通过专业化来完成。
class A
{
public:
template <typename ... Args>
A(const wstring &, Args ... );
template <typename ... Args>
A(const string &, Args ...);
};
要使一个只与一种类型完全匹配的模板在语义上不是模板: - )
阅读完评论后,我得到了这个解决方案:
class foo
{
public:
template <typename ... Args>
foo( const string &&x, Args ... ) { cout << "Using string" << endl; }
template <typename ... Args>
foo( const wstring &&x, Args ...) { cout << "Using wstring" << endl; }
};
int main()
{
foo("123");
foo(L"123");
foo("123", 1);
foo(L"123", 1.11);
return 0;
}
并按预期返回:
Using string
Using wstring
Using string
Using wstring