如何检查两个类型是否来自同一个模板类

jur*_*lak 6 c++ templates types

我想检查两种类型是否相同,但不管它们的模板参数如何.像这样的东西:

template<class T>
class A {};
class B {};

int main() {
    cout << std::is_same_template<A<int>, A<string>>::value << endl; // true
    cout << std::is_same_template<A<int>, B>::value << endl; // false
}
Run Code Online (Sandbox Code Playgroud)

我知道std::is_same检查两种类型是否匹配.

我需要这个的原因:我有一个可以用任何类型调用的模板化方法,但我想禁止使用类型调用A(模板化),可能使用a static_assert.是A不是模板,我相信它可以很容易地使用来完成std::is_same,但现在,我有一个问题...

编辑:我可以手动排除A为几个常见的Ts,使用,我正在寻找一种方法来做所有T:

static_assert(!std::is_same<parameter_type, A<int>>::value, "Cannot use this function with type A<T>");
static_assert(!std::is_same<parameter_type, A<double>>::value, "Cannot use this function with type A<T>");
static_assert(!std::is_same<parameter_type, A<bool>>::value, "Cannot use this function with type A<T>");
Run Code Online (Sandbox Code Playgroud)

Nik*_*uev 5

好的,这如何:

#include <iostream>

template<class T>
struct A {};
struct B {};

template <typename T>
struct should_reject { static constexpr bool value = false; };

template <typename T>
struct should_reject<A<T>> { static constexpr bool value = true; };

template <typename T>
void rejectA(T t)
{
    std::cout << should_reject<T>::value << std::endl;
}

int main() {
    rejectA(B());         // false
    rejectA(1);           // false
    rejectA(1.0);         // false
    rejectA(A<B>());      // true
    rejectA(A<int>());    // true
    rejectA(A<double>()); // true
}
Run Code Online (Sandbox Code Playgroud)


bit*_*ift 5

我想出了一种比@NikitaKakuev 的答案更简单的方法,目前在我的一个项目中使用。

template<typename, typename>
constexpr bool is_same_template{false};

template<
    template<typename...> class T, //typename T in C++17
    typename... A,
    typename... B
>
constexpr bool is_same_template<
    T<A...>,
    T<B...>
>{true};
Run Code Online (Sandbox Code Playgroud)

当前唯一的问题是混合类型和类型名的模板,即。std::array<int, 10>.
为了克服这个限制,需要专业化。

用法:

bool b = is_same_template<std::string, std::wstring>;  //true
//both are typedefs of std::basic_string
Run Code Online (Sandbox Code Playgroud)

编辑:根据@Helix 在下面评论中的要求,专业化std::array(或具有相同签名的任何其他模板):

template<
    template<typename, std::size_t> class T, //typename T in C++17
    typename TA, std::size_t NA,
    typename TB, std::size_t NB
>
constexpr bool is_same_template<
    T<TA, NA>,
    T<TB, NB>
>{true};
Run Code Online (Sandbox Code Playgroud)