【问题标题】:Build tuple from heterogeneous initializer list at function call在函数调用时从异构初始化列表构建元组
【发布时间】:2017-11-05 19:18:01
【问题描述】:

考虑以下函数

template <class... T, class... U>
void f(std::tuple<T...> t, std::tuple<U...> u)
{
    std::cout << sizeof...(T) << " " << sizeof...(U) << std::endl;
}

int main(int argc, char* argv[]) 
{
    f({3, 3.5, "Hello World!"}, {'a', std::string("b")}); // Fails
    return 0;
}

在 C++17 中是否有任何方法可以修改函数签名,以便标记为“失败”的行可以工作? (保持那条线不变)。

【问题讨论】:

    标签: c++ initialization tuples c++17 aggregate-initialization


    【解决方案1】:

    我的猜测是 简短的回答是否定的
    粗略地说,{ args... } 不是元组,您会遇到与 C++14 中相同的推导和转换问题。


    话虽如此,在 C++14/17 中,您可以这样做来模拟它(最小的工作示例):

    #include<iostream>
    #include<string>
    #include<tuple>
    #include<utility>
    
    template <class... T, class... U>
    void f_(std::tuple<T...> t, std::tuple<U...> u) {
        std::cout << sizeof...(T) << " " << sizeof...(U) << std::endl;
    }
    
    template<typename... T>
    auto f(T... t) {
        return [tup{std::make_tuple(t...)}](auto... u) {
            f_(std::move(tup), std::make_tuple(u...));
        };
    }
    
    int main(int argc, char* argv[]) {
        f(3, 3.5, "Hello World!")('a', std::string("b"));
        return 0;
    }
    

    通用 lambda 可以为您带来魔力,并且您可以通过额外的间接级别获得与您想要的类似的东西(这通常有助于解决任何问题)。


    在 C++17 中,您也可以这样做:

    f(std::tuple{3, 3.5, "Hello World!"}, std::tuple{'a', std::string("b")});
    

    这是直接从对构造函数的调用中推导出的参数类型,而不是显式指定它们。使用别名,您甚至可以更进一步,将调用点处的表达式简化为如下所示:

    f(T{3, 3.5, "Hello World!"}, T{'a', std::string("b")});
    

    无论如何,您为此牺牲了可读性,从我的角度来看,这不值得。

    【讨论】:

      【解决方案2】:

      在 C++17 中,你可以这样写:

      f(std::tuple{3, 3.5, "Hello World!"}, std::tuple{'a', std::string("b")});
      

      之前,你可以使用std::make_tuple:

      f(std::make_tuple(3, 3.5, "Hello World!"), std::make_tuple('a', std::string("b")));
      

      但没有什么可以让该行保持不变并保留函数模板。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-13
        • 1970-01-01
        • 1970-01-01
        • 2020-08-30
        • 1970-01-01
        • 2010-09-14
        相关资源
        最近更新 更多