如何从 C++ 模板中的参数包构造对象?

How can one construct an object from a parameter pack in a C++ template?

鉴于以下情况,如何从参数包中正确构造未知类型的对象?

template < typename... Types >
auto foo( Types&&... types ) {
    auto result =  Types{ }; // How should this be done?
    // Do stuff with result
    return result;
}

我希望模板函数只在匹配类型的情况下被调用,所以参数包中的所有内容都应该是相同的类型。例如,如果我需要使用 decltype,我引用哪个项目并不重要(注释部分中的相关代码否则会导致编译错误)。

这是一种方法(假设我们谈论的是相对简单的类型,可以支持复制):

template < typename... Types >
auto foo( Types&&... types ) {
    return std::array{types...}[0];
}

这是另一种更复杂但有效的方法,它对类型没有额外限制:

#include <tuple>

template < typename... Types >
auto foo( Types&&... types ) {
    using tup_t = std::tuple<Types...>;
    auto result =  std::tuple_element_t<0, tup_t>{}; 

    // Do stuff with result
    return result;
}


// auto k = foo(); // compile error

auto z = foo(10); // z is 0-initialized int

由于参数包中的所有类型都是相同的,所以可以使用std::common_type_t,它给出了一个参数包中所有类型都可以转换为的类型。

template <typename... Types>
auto foo(Types&&... types) {
    auto result = std::common_type_t<Types...>{};
    // Do stuff with result
    return result;
}

由于参数包中的所有类型都是相同的,可以先使用逗号运算符展开参数包,然后使用decltype获取最后一个操作数的类型。

template<typename... Types>
auto foo(Types&&... types) {
  auto result = decltype((Types{}, ...)){ };
  // Do stuff with result
  return result;
}

Demo.