c++ - 具有相同类型的可变参数模板参数的构造函数无法编译
问题描述
我正在尝试构建一个使用可变参数模板构造函数的类。模板参数都是相同的类型。
我正在使用带有 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);
解决方案
模板参数都是相同的类型。[...] 这在 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...};
}
所以只有Ts...
在第一个之后的所有类型T
都与T
缺点:适用于
Alfa alfa{1, 2, 3, 4};
但给出了一个错误
Alfa alfa{1l, 2l, 3, 4l}; <-- 3 isn't long
因为3
可转换为long
( 1l
is long
) 但 is 不是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...};
}
推荐阅读
- ssas - MDX - 每个子组的前 N 个元素
- spring - @Autowired 不应该在没有 @RunWith(SpringRunner.class) 的情况下工作,但可以
- database - 是否可以从不允许 expdp 的损坏安装中恢复 Oracle 数据?
- c++ - 如何定义具有特定格式的类模板以获取模板参数?例如:Fn(Args...)
- performance - Haskell 计算性能
- excel - 变量未加载范围值
- python - AttributeError:“字节”对象在 Python 套接字库上没有“读取”属性
- wordpress - 错误:WordPress 不存在“Access-Control-Allow-Origin”标头
- android - 我正在努力让我的 Android 项目视图响应不同尺寸的屏幕
- java - RestController 中的 ControllerAdvice、ExceptionHandler 和 try catch 块