c++ - 具有相同类型的可变模板参数的构造函数无法编译

标签 c++ c++17 variadic-templates template-argument-deduction

我正在尝试构造一个使用可变模板构造函数的类。 模板参数都是相同的类型。

我正在使用带有 C++ 17 的 Visual C++ 编译器,但代码无法构建;这段代码实际上使编译器崩溃。

这在 C++17 中可能吗?

 struct Alfa {
     template<int... T>
     Alfa(const T&... all_args) {
         std::tuple<T...> data(all_args...);       
     }    
 };

 Alfa alfa(1,2,3,4);

最佳答案

The template arguments are all the same type. [...] is that possible in C++17 ?

是的,这是可能的。

但不是以如此简单的方式,并且有一些缺点。

您可以编写一个接受不同类型参数的构造函数;这很简单

 template <typename ... Ts>
 Alfa (const Ts & ... as) 
  { std::tuple<Ts...> data{as...}; } 

但这允许 Ts... 类型不同。

您可以使用 SFINAE 强制所有类型都相同,如下所示

 template <typename T, typename ... Ts,
           std::enable_if_t<(std::is_same_v<T, Ts> && ...), bool> = true>
 Alfa (T const & a0, Ts const & ... as)
  {
     std::tuple<T, Ts...> data0{a0, as...};       
     std::array           data1{a0, as...};
  }  

因此,仅当第一个 T 之后的所有 Ts... 类型与 T 完全相同时,您的构造函数才会启用

缺点:适用于

   Alfa alfa{1, 2, 3, 4};

但出现错误

   Alfa alfa{1l, 2l, 3, 4l};  <-- 3 isn't long

因为 3 可转换为 long(1llong),但不是 long .

因此您可以检查以下 Ts... 是否可以转换为 T,而不是它们是否相等

 template <typename T, typename ... Ts,
           std::enable_if_t<(std::is_convertible_v<Ts, T> && ...), bool> = true>
 Alfa (T const & a0, Ts const & ... as)
  {
     std::tuple<T, Ts...>             data0{a0, as...};       
     std::array<T, sizeof...(Ts)+1u>  data1{a0, as...};
  }   

但是这样你就可以让 T 比其他类型更加重要(如果所有 Ts... 都可以转换为 T 则有效,但是如果 T 可转换为 Ts... 之一,则不会),所以我认为更好的解决方案是检查是否存在通用类型

 template <typename ... Ts,
           typename CT = std::common_type_t<Ts...>>
 Alfa (Ts const & ... as)
  {
     std::tuple<Ts...>              data0{as...};       
     std::array<CT, sizeof...(Ts)>  data1{as...};
  }  

关于c++ - 具有相同类型的可变模板参数的构造函数无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59856345/

相关文章:

c++ - 如何在 VBA 中声明接受 XlfOper (LPXLOPER) 类型参数的函数?

c++ - C++中的Strtok异常行为

c++ - 在匿名命名空间中定义自定义相等运算符

c++ - 如何编写通用特征以将 T::value_type 与其他特征相匹配?

c++ - Variadic 模板函数名称查找无法找到特化

c++ - 在 Rcpp 中找到 vector 的最小值

c++ - 将函数传递给可变函数模板

c++ - clang 5:std::optional 实例化参数类型的 std::is_constructible 特征

c++ - std::invoke 不喜欢可变参数模板成员函数?

c++ - 在 C++14 的 Variadic 模板中选择可调用类型和不可调用类型是否有一个优雅的解决方案