【问题标题】:C++0x: how to get variadic template parameters without reference?C++0x:如何在没有参考的情况下获取可变参数模板参数?
【发布时间】:2011-02-26 06:13:24
【问题描述】:

鉴于以下人为的(是的,糟糕的)示例:

template<typename... Args>
void something(Args... args)
{
    std::tuple<Args...> tuple; // not initializing for sake of example
    std::get<0>(tuple) = 5;
}

如果你这样称呼它就可以了:

int x = 10;
something<int>(x);

但是,如果你这样称呼它是行不通的:

int x = 10;
something<int&>(x);

由于分配给 5。假设我无法在定义元组时对其进行初始化,那么在将类型指定为引用时如何使其工作?

具体来说,我希望元组是 std::tuple&lt;int&gt;,即使 Args...int&amp;

实际用例涉及将字符串反序列化为元组,其中Args... 是函数的参数类型,然后通过解包元组来调用该函数。这一切都很好,除非函数通过引用获取参数。

我正在使用 gcc 4.5.2,但会接受尚未在此编译器中实现的答案。

【问题讨论】:

    标签: c++ templates c++11 variadic-templates


    【解决方案1】:

    我不明白你的问题。这段代码在 GCC 上工作得很好,我看不出它为什么不能工作。

    #include <tuple>
    
    template<typename... Args>
    void something(Args... args)
    {
      std::tuple<Args...> tuple{args...};
      std::get<0>(tuple) = 5;
    }
    
    int main() {
      int x = 10;
      something<int&>(x);
    }
    
    [js@HOST2 cpp]$ g++ -std=c++0x main1.cpp
    [js@HOST2 cpp]$
    

    我不知道你所说的“初始化模板”是什么意思。


    既然你现在已经更新了问题,我可以更新我的答案

    template<typename... Args>
    void something(Args... args)
    {
      std::tuple<typename std::decay<Args>::type...> tuple;
      std::get<0>(tuple) = 5;
    }
    

    decay 删除 const / volatile,删除引用并将数组和函数类型分别转换为元素和函数指针。这似乎就是您要寻找的东西。

    【讨论】:

    • 抱歉,意思是“如果我无法初始化元组”,IE 不能在示例中包含 {args...}。
    • @Sydius 然后不要传递引用类型。您必须初始化一个引用。如果您还没有初始化引用,您希望 get&lt;0&gt;(tuple) = 5 分配给什么?
    • 我对我的问题进行了澄清。即使模板用于参考,我也希望元组不要参考。实际用例要复杂得多;这只是一个人为的例子来说明问题。
    • @Sydius 那么我认为你应该描述更复杂的用例(不是它的代码,只是它的情况)。所有这一切都只是涉足真正的问题,而我提出的解决方案只是解决这个减少的测试用例的一种方法,这可能不是您更复杂用例的真正解决方案。
    • 听起来正是我想要的,但在 gcc 4.5.2 中我得到了expected a type, got ‘std::decay&lt;Args&gt;::type ...’
    【解决方案2】:

    你试过std::tuple&lt;std::remove_reference&lt;Args&gt;...&gt;吗?

    【讨论】:

    • 我想我可能做错了,但是当我尝试这样做时,我得到:error: no match for ‘operator=’ in ‘std::get [with long unsigned int __i = 0ul, _Elements = {std::remove_reference&lt;int&amp;&gt;}, typename std::__add_ref&lt;typename std::tuple_element&lt;__i, std::tuple&lt;_Elements ...&gt; &gt;::type&gt;::type = std::remove_reference&lt;int&amp;&gt;&amp;](((std::tuple&lt;std::remove_reference&lt;int&amp;&gt; &gt;&amp;)(&amp; tuple))) = 5’
    • 当你使用元函数时,你必须访问它的返回类型,除非你真的想把元函数用作类型本身。我在我的帖子里忘记了。我认为语法应该是std::remove_reference&lt;Args&gt;::type ...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    • 2011-03-16
    • 1970-01-01
    • 2020-11-29
    • 2012-05-03
    • 2015-09-14
    • 1970-01-01
    相关资源
    最近更新 更多