包含可变参数包的第一个可转换类型的别名的Struct

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来实现解决方案.我不能使用除标准库之外的任何东西.

Jon*_*nas 4

您可以使用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)