【问题标题】:Template type paremeter not expanding as desired模板类型参数未按需要扩展
【发布时间】:2021-03-05 07:31:01
【问题描述】:

当我注意到模板有多么强大时,我正在尝试c++ TMP。 但在某些时候,我想知道为什么下面的代码无效,但它使用可变参数模板类型扩展(1)。当非类型可变参数扩展工作正常时(2)。划分没有意义,因为两个扩展参数都将不可用。还是我的编译器有问题。 clang++ std=c++20

  • 测试
    template<typename Y> struct Exp{
        static const bool useless=false;
    };
    template<typename... T> auto initAll1(int forAll,T...ts){
        std::array a={(ts,forAll)...};
    }
    template<typename... T> auto initAll2(int forAll){
        std::array a={(T,forAll)...};
    }
    template<typename... T> auto initAll3(int forAll){
        std::array a={(Exp<T>::useless,forAll)...};
        return a;
    }
    

    我说的是initAll2。它不起作用,我发了initAll3以避免错误。

  • 【问题讨论】:

    • 您正在扩展为std::array 的初始化列表。 (T, forAll) 是一个表达式(, 是一个始终返回右侧的运算符)。因此,您将类型名称放入表达式中,这是没有意义的。您的意思是使用T{} 并用这些类型的默认值填充它吗?
    • @parktomatomi - 恕我直言,您应该在答案中扩展评论(但关于T{}...如果T不是默认可构造的呢?使用Exp&lt;T&gt;::useless(但也许只是Exp&lt;T&gt;{} 里面没有useless)是一种避免问题的方法)
    • @max66 没错。但在这两种情况下,构建无用对象都是有代价的。如果std::array a={(T,forAll)...}; 工作会更容易。
    • @D.Sikilai - 考虑到现代编译器的优化,我认为废弃的Exp&lt;T&gt;{} 对象没有实际成本(也许Exp 可以减少为template &lt;typename&gt; struct Exp {};

    标签: c++ variadic-templates variadic-functions c++20


    【解决方案1】:

    正如 max66 的评论所说,选项 3 可能不会有任何运行时开销。但如果你想要更干净的东西,你可以这样做:

    template<typename... T>
    auto initAll2(int forAll){
        std::array a={std::conditional_t<true, int, T>{ forAll }...};
    }
    

    【讨论】:

    • 使用std::conditional_t的好主意;无论如何,问题是关于为什么不工作(T, forAll)...;我认为您应该从答案中的评论中转录和扩展有关逗号运算符的部分。
    猜你喜欢
    • 2021-12-28
    • 1970-01-01
    • 2012-03-27
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多