【问题标题】:How to check if two types come from the same templated class [duplicate]如何检查两种类型是否来自同一个模板类[重复]
【发布时间】:2016-01-24 06:01:23
【问题描述】:

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

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
}

我知道std::is_same 用于检查两种类型是否完全匹配。

我需要这个的原因: 我有一个可以使用任何类型调用的模板化方法,但我想禁止使用A(模板化)类型调用它,可能使用static_assert。如果A 没有模板化,我相信使用std::is_same 可以轻松完成,但是现在,我有一个问题......

编辑: 我可以为一些常见的 T 手动排除 A,使用,我正在寻找一种方法来为所有 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>");

【问题讨论】:

  • 两种类型不一样,如果它们的模板参数不同的话。因此,A&lt;int&gt;A&lt;float&gt; 远不是同一种类型。
  • 嗯,我很清楚这一点,这就是为什么我不能使用std::is_same。我要问的是,如果有办法不那么严格地比较,让 A 和 A 比较相等,而 A 和 B 不比较?
  • 您可以通过模板特化的方式使用相反的方法,因此只接受允许的类并定义一个空/损坏/抛出/其他函数。
  • 我自己也想到了这一点,但这并不是真正的最佳选择,因为我希望我的函数可用于任何类型,除了这个。这需要我写很多专业化:) 因为我可以禁止固定类型,所以我宁愿禁止 A 用于一些常见的 T。
  • 你不能重构A 以便有一个模板化的组件/委托,这样你就可以设法将is_sameA 一起使用吗?

标签: c++ templates types


【解决方案1】:

我想出了一个比@NikitaKakuev 的答案更简单的方法,目前用于project of mine

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};

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

用法:

bool b = is_same_template<std::string, std::wstring>;  //true
//both are typedefs of std::basic_string

编辑:根据@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};

【讨论】:

  • 嘿,我想知道您是否可以更新您的答案以包含该专业的示例?
  • @Helix 你去吧。
【解决方案2】:

好的,这个怎么样:

#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
}

【讨论】:

  • 我希望你的例子中的这两个比较相等,但你给了我一些想法。我可以调整功能以拒绝定义了 cetain typdef 的类型吗?或者甚至是运行时值......(并且反对票不是我的)
  • 哦,我完全误解了你的问题。很抱歉。
  • 我已经编辑了我的答案。
  • 仍然不是我想要的,但我认为我实际上可以从这里开始解决。 A should_reject 应该对所有 A 都为 true,但默认为 false。
  • 检查更新版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-07
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多