Kri*_*abó 6 c++ metaprogramming
我有typename T1,我有一个参数包typename... Variadic.
我想创建一个结构,其中包含可以转换为using Type = ...参数包中第一个类型的使用别名T1.到目前为止,我尝试了以下内容:
template<typename T1, typename T2, typename... Variadic>
struct VariadicConvertibleType
{
using Type = std::enable_if<std::is_convertible<T1, T2>::value, T2>::type;
};
Run Code Online (Sandbox Code Playgroud)
对于前两种类型,这可能是使用SFINAE的潜在解决方案,但我需要使用递归将其扩展到包中的所有类型.到目前为止,我的所有尝试都失败了,因为您无法将条件放入使用别名声明.否则可以使用类似的东西:
template<typename T1, typename T2, typename... Variadic>
struct VariadicConvertibleType
{
using Type = std::is_convertible<T1, T2>::value ? T2 : VariadicConvertibleType<T1, Variadic...>::Type;
};
Run Code Online (Sandbox Code Playgroud)
我可以使用一切(包括)C++ 14来实现解决方案.我不能使用除标准库之外的任何东西.
您可以使用std::conditional,如下所示:
template<typename T1, typename T2, typename... Variadic>
struct VariadicConvertibleType
{
using type = std::conditional_t<std::is_convertible<T1, T2>::value, T2, typename VariadicConvertibleType<T1, Variadic...>::type>;
};
template<typename T1, typename T2>
struct VariadicConvertibleType<T1, T2>
{
static_assert(std::is_convertible<T1, T2>::value);
using type = T2;
// Alternative base-case
// using type = std::conditional_t<std::is_convertible<T1, T2>::value, T2, T1>;
};
Run Code Online (Sandbox Code Playgroud)
我提供了两种基本情况(评论中的另一种)。第一个(我想这就是你想要的)使用 (C++14) static_assertifT1不能转换为Variadic. 在这种情况下,替代基本情况设置type为。T1
测试
#include <iostream>
#include <type_traits>
#include <typeinfo>
int main()
{
using my_type_1 = typename VariadicConvertibleType<int, double, float>::type;
std::cout << typeid(my_type_1).name() << '\n'; // double
using my_type_2 = typename VariadicConvertibleType<int, int*, float>::type;
std::cout << typeid(my_type_2).name() << '\n'; // float
using my_type_3 = typename VariadicConvertibleType<int, int*, float*>::type;
std::cout << typeid(my_type_3).name() << '\n'; // Complile error with the primary base-case, and int with the alternative base-case.
}
Run Code Online (Sandbox Code Playgroud)