繁体   English   中英

使用多个模板参数包应用 CTAD

[英]Applying CTAD with multiple template parameter packs

遵循此处提供的一些解决方案如何在可变参数模板中包含多个参数包? ,我希望将多个参数包应用于一个类并使用 CTAD 使该类更有用。

这是我想出的(在Coliru 上),但这给出了:

错误:类模板参数推导失败

这是我试过的代码:

// 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;
}

首先,使用范围解析操作符时没有进行 CTAD,因此永远不能使用Foo:: 您必须明确指定此Foo的模板参数。

我建议你只需移动Bar1Bar2Foo偏特到的命名空间范围和使用

Foo{Bar1(1, 2.0, 3), Bar2(100, 23.4, 45)};

反而。


然后你会得到一个错误,即Foo推导失败。 这是因为隐式推导指南只考虑模板中的构造函数。 但是您要使用的构造函数位于部分特化中,而不是主模板中。

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

template <typename... Args1, typename... Args2>
Foo(Bar1<Args1...>, Bar2<Args2...>) -> Foo<Typelist<Args1...>, Typelist<Args2...>>;

然后你会得到一个错误,说没有构造函数是可行的。 这是因为您将Bar1<Args1...>& b1Bar2<Args2...>& b2作为非const左值引用,但您为它们提供了纯右值。 const左值引用无法绑定到右值,因此会出现错误。 要么按值取参数,要么按const左值引用。


最后你会得到一个错误_b1_b2没有默认构造函数,这是真的。 它们是必需的,因为您在构造函数中默认初始化了_b1_b2 您稍后才为它们分配值。

因此,要么添加默认的构造函数来Bar1Bar2或更好地利用初始化而不是分配:

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

在所有这些步骤之后,代码应该可以编译了。 我不确定你的目标到底是什么,所以不完全确定这是否会做你想要的。

暂无
暂无

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

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