繁体   English   中英

如何使用std :: enable_if有条件地选择一个可变参数构造函数?

[英]How to use std::enable_if to conditionally select a variadic constructor?

我试图创建一个类,它应该从其他类继承构造函数,但不从这些类本身继承。

在我的类初始化期间的某个时刻,我想使用完美转发来创建一个类型的对象,其构造函数与给定的参数匹配。

除了没有参数的默认构造函数之外,不存在歧义。

这是我的代码:

#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无法自动扣除模板args(我认为)
  • 由于我使用构造函数,因此无法在返回值上使用enable_if
  • enable_if添加另一个默认参数将不起作用,因为构造函数是可变参数
  • 当我从函数参数中删除enable_if ,编译器会抱怨无效的重载(当然)

有没有一种优雅的方法来解决这个问题?

编辑:标准允许的一个隐式转换不应该出现在我的类中。 [示例代码编辑]

与上面的示例一起使用的一个解决方案是定义单个可变参数构造函数并将参数完美地转发到条件初始化函数。 但是,我想避免这种开销,因为成员需要默认构造,这在其他情况下可能不起作用。

(如果事情可以更清楚,请随时编辑问题)

我无法理解问题以及解决方案。 如果我想为方法或构造函数使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM