C++ 使用decltype(func<;T>;())计算不完整的类型

C++ 使用decltype(func<;T>;())计算不完整的类型,c++,c++17,typetraits,incomplete-type,C++,C++17,Typetraits,Incomplete Type,假设我有以下代码来计算基于给定类型的新类型: struct S1; struct S2; // S1 and S2 are incomplete here template<typename> struct get_type { using Type = S2; }; template<> struct get_type<int> { using Type = S1; }; template<typename T> usin

假设我有以下代码来计算基于给定类型的新类型:

struct S1;
struct S2;

// S1 and S2 are incomplete here

template<typename> struct get_type {
    using Type = S2;
};

template<> struct get_type<int> {
    using Type = S1;
};

template<typename T> using Get_type = typename get_type<T>::Type;

struct S1 {};
struct S2 {};

void foo() {
   Get_type<int> s1;
   Get_type<long> s2;
}
无法工作,因为
S1
S2
不完整。为了避免这个问题,我可以使用
type\u identity
“包装器”:

模板结构类型\u标识{
使用类型=T;
};
模板自动获取_类型(){
如果constexpr(std::is_same_v)
返回类型_标识{};
其他的
返回类型_标识{};
}
使用Get\u type=typename decltype(Get\u type())的模板:type;
或指针:

template<typename T> auto get_type() {
    if constexpr (std::is_same_v<T, int>)
        return static_cast<S1*>(nullptr);
    else
        return static_cast<S2*>(nullptr);
}

template<typename T> using Get_type = std::remove_pointer_t<decltype(get_type<T>())>;
模板自动获取类型(){
如果constexpr(std::is_same_v)
返回静态_cast(nullptr);
其他的
返回静态_cast(nullptr);
}
使用Get\u type=std::remove\u pointer\t;

有哪些替代方法?(我甚至会说“更好”,但我害怕被指责提出基于意见的问题。)

老实说,我不认为你能打败
type\u identity
这里libstdc++类型特征最近已经针对不完整的类型进行了强化:。此修补程序中使用的技术可能会引起您的兴趣。您可以使用未定义的
模板T rval(T*)
decltype(rval(pointer\u chooser())
,但我不确定这在实质上是否更好。
template<class T> struct type_identity {
    using Type = T;
};

template<typename T> auto get_type() {
    if constexpr (std::is_same_v<T, int>)
        return type_identity<S1>{};
    else
        return type_identity<S2>{};
}

template<typename T> using Get_type = typename decltype(get_type<T>())::Type;
template<typename T> auto get_type() {
    if constexpr (std::is_same_v<T, int>)
        return static_cast<S1*>(nullptr);
    else
        return static_cast<S2*>(nullptr);
}

template<typename T> using Get_type = std::remove_pointer_t<decltype(get_type<T>())>;