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

c – 如何使用std :: enable_if有条件地选择一个可变的构造函数?,第1张

概述我试图使一个类应该继承其他类的构造函数,但不继承这些类本身. 在我的类的初始化期间,我想使用完美转发来创建一个类型的对象,其构造函数与给定的参数相匹配. 除了没有参数的默认构造函数之外,不应有歧义. 这是我的代码: #include <string>using namespace std;//NOTE: this class is just an example to demonstrat 我试图使一个类应该继承其他类的构造函数,但不继承这些类本身.

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

除了没有参数的默认构造函数之外,不应有歧义.

这是我的代码:

#include <string>using namespace std;//NOTE: this class is just an example to demonstrate the problemclass 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>::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时,编译器会抱怨无效重载(当然)

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

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

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

(如果事情可以更清楚,随意编辑这个问题)

解决方法 使模板化构造函数仅适用于某些类型的标准方法是使用默认的模板参数,如下所示:
#include <type_traits>#include <utility>struct Foo{    bar x;    template <typename ...Args,typename = std::enable_if_t<std::is_constructible<bar,Args...>::value>>    Foo(Args &&... args)    : x(std::forward<Args>(args)...)    { }};

(这里,enable_if_t< T>是用于typename enable_if< T> :: type的别名,它是C 14中的库的一部分)

一个不同的,不相关的问题是根据参数选择不同的构造函数.这个问题可以通过引入私有,不同的重载,然后使公共构造函数发送到这些私有版本来解决(请参阅DyP的解决方案,如果你愿意,我可以详细说明).但是,您仍然需要SFINAE控制您的公共构造函数,以允许只匹配任何一个私有版本的构造函数.在你的情况下:

template <typename ...Args,typename = std::enable_if_t<              std::is_constructible<std::string,Args...>::value> ||              std::is_constructible<std::wstring,Args...>::value>>String(Args &&... args): String({},std::forward<Args>(args)...)//       ^^^{ }

现在,我们只需要为第一个私有参数组成一个任意的默认可构造类型的族:

class String{    std::string s;    std::wstring ws;    template <int> struct X {};    template <typename ...Args,typename = std::enable_if_t<                  std::is_constructible<std::string,Args...>::value>>    String(X<1>,Args &&... args) : s(std::forward<Args>(args)...),ws() { } //        ^^^^^    template <typename ...Args,typename = std::enable_if_t<                  std::is_constructible<std::wstring,Args...>::value>>    String(X<2>,Args &&... args) : s(),ws(std::forward<Args>(args)...) { } //        ^^^^^public: // as above};
总结

以上是内存溢出为你收集整理的c – 如何使用std :: enable_if有条件地选择一个可变的构造函数?全部内容,希望文章能够帮你解决c – 如何使用std :: enable_if有条件地选择一个可变的构造函数?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1254453.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存