1

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

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

我希望模板函数只能用匹配的类型调用,所以参数包中的所有内容都应该是相同的类型。例如,如果我需要使用,我引用哪个单独的项目都没有关系decltype(注释掉部分中的相关代码会导致编译错误)。

4

3 回答 3

1

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

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
于 2021-12-08T22:55:01.793 回答
1

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

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

演示。

于 2021-12-08T23:57:48.650 回答
0

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

template <typename... Types>
auto foo(Types&&... types) {
    auto result = std::common_type_t<Types...>{};
    // Do stuff with result
    return result;
}
于 2021-12-08T23:44:14.260 回答