首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多模板参数包应用CTAD

多模板参数包应用CTAD
EN

Stack Overflow用户
提问于 2020-03-18 08:30:46
回答 1查看 166关注 0票数 2

按照这里提供的一些解决方案( 如何在可变模板中包含多个参数包? ),我希望将多个参数包应用到类中,并使用CTAD使类更加可用。

下面是我(在柯尔鲁上)提出的,但这给出了如下结果:

错误:类模板参数演绎失败

下面是我尝试过的代码:

代码语言:javascript
复制
// A template to hold a parameter pack
template < typename... >
struct Typelist {};

// Declaration of a template
template< typename TypeListOne 
        , typename TypeListTwo
        > 
struct Foo;     

// A template to hold a parameter pack
template <typename... Args1, typename... Args2>
struct Foo< Typelist < Args1... >
                 , Typelist < Args2... >
                 >{
    template <typename... Args>
    struct Bar1{
        Bar1(Args... myArgs) {
            _t = std::make_tuple(myArgs...);
        }
        std::tuple<Args...> _t;
    };

    template <typename... Args>
    struct Bar2{
        Bar2(Args... myArgs) {
            _t = std::make_tuple(myArgs...);
        }
        std::tuple<Args...> _t;
    };

    Bar1<Args1...> _b1;
    Bar2<Args2...> _b2;

    Foo(Bar1<Args1...>& b1, Bar2<Args2...>& b2) {
        _b1 = b1;
        _b2 = b2;
    }
};

int main()
{

    Foo{Foo::Bar1(1, 2.0, 3), Foo::Bar2(100, 23.4, 45)};
    return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-18 09:32:33

首先,在使用范围解析操作符时不执行CTAD,因此永远不能使用Foo::。必须显式指定此Foo的模板参数。

我建议您只需将Bar1Bar2移出Foo部分专门化,进入命名空间范围并使用

代码语言:javascript
复制
Foo{Bar1(1, 2.0, 3), Bar2(100, 23.4, 45)};

而不是。

然后,您将得到一个错误,对Foo的扣减失败。这是因为隐式演绎指南只考虑主模板中的构造函数。但是要使用的构造函数是部分专门化,而不是主模板。

因此,您需要自己添加一个适当的扣减指南,例如:

代码语言:javascript
复制
template <typename... Args1, typename... Args2>
Foo(Bar1<Args1...>, Bar2<Args2...>) -> Foo<Typelist<Args1...>, Typelist<Args2...>>;

然后,您将得到一个错误,即没有任何构造函数是可行的。这是因为您将Bar1<Args1...>& b1Bar2<Args2...>& b2作为非const lvalue引用,但是您为它们提供了prvalue。非const lvalue引用不能绑定到lvalue,因此您将得到一个错误。要么按值获取参数,要么通过const lvalue引用.

最后,您将得到一个错误,即_b1_b2没有默认构造函数,这是正确的。它们之所以需要,是因为您在构造函数中默认初始化_b1_b2。您只是在以后才给它们赋值。

因此,要么向Bar1Bar2添加默认构造函数,要么更好地使用初始化而不是赋值:

代码语言:javascript
复制
Foo(const Bar1<Args1...>& b1, const Bar2<Args2...>& b2) : _b1(b1), _b2(b2) { }

在完成所有这些步骤之后,代码应该编译。我不知道你的目标到底是什么,所以我不完全确定这是否能做你想做的事情。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60735887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档