【问题标题】:C++: Way around dependent templatesC++:绕过依赖模板
【发布时间】:2021-04-01 18:18:52
【问题描述】:

我有一个这样的类模板:

    template <typename T1, typename T2>
    class ClassName {
        // Members variables and Functions based on the template parameter types
    };

(T1, T2) 只能是 (class A, class B)(class C, class D)。 因此,仅 T1 就足以确定 T2。 有什么办法只取T1作为参数,写同一个类吗?如果是,怎么做?

【问题讨论】:

  • 如果总是T1,为什么还要有T3
  • 如果只有当你可以enumerate所有可能的选项时有一个工具可以使用......
  • 不清楚会“重写”什么,因为这个类中没有任何内容。由于T3只是T1,而T2只是翻转T1的值,你是问如何写一个类型是另一个类型的翻转类型?
  • @ChrisMM 我必须根据 T1 决定 T3,但只将 T1 作为参数。也许,我的 int 和 float 示例引起了混乱。
  • 如果示例没有说明意图,也许添加一个更好的示例? :)

标签: c++ c++11 c++14


【解决方案1】:

如果您的模板仅依赖于单个参数,则不应使用 2 个参数声明它。您可以将std::conditionalstd::is_same 一起使用来声明条件别名。

如果你愿意:

(T1, T2) 只能是(A 类,B 类)或(C 类,D 类)

如果“仅”是指:用户只为 AC 实例化,在这种情况下,T2 应该是 B / D

#include <type_traits>

struct A {};
struct B {};
struct D {};

template <typename T>
struct Foo {
  using T1 = T;
  using T2 = std::conditional_t<std::is_same_v<A, T>, B, D>;
};

Foo&lt;A&gt;::T2BFoo&lt;C&gt;::T2D。实际上Foo&lt;T&gt;::T2D 对于任何不是AT。换句话说,如上所述,前提是它只为AC实例化。如果模板本身应该确保只有 AC 的实例化有效,您可能需要添加 static_assert(再次使用 std::is_same 来检查 T 是否属于允许的类型)。

【讨论】:

  • 我认为using T3 = T 也是有效的,简单一点。
  • 我会在这里积极推荐反对 SFINAE,因为这会导致难以诊断编译器错误。更喜欢static_assert
  • @largest_prime_is_463035818 我认为这是我正在寻找的解决方案。谢谢。在旁注中,是否有任何重复?如果没有,请让我知道问题的任何更改(以便更好地参考)
【解决方案2】:

枚举你的配置:

enum class ClassConfigEnum { AB, CD};
template<ClassConfigEnum config> struct ClassConfig;
template<> struct ClassConfig<AB> {
    using T1 = A;
    using T2 = B;
};
template<> struct ClassConfig<CD> {
    using T1 = C;
    using T2 = D;
};

然后让类使用枚举配置

template <ClassConfigEnum config>
class ClassName {
    using T1 = ClassConfig<config>::typename T1;
    using T2 = ClassConfig<config>::typename T2;
};

【讨论】:

  • 针对一般情况的惊人解决方案。我一直在研究这种方法。谢谢
【解决方案3】:

你可以写一个类型特征:

#include <iostream>
#include <type_traits>

struct A {};
struct B {};
struct C {};
struct D {};

template <typename Type> struct Dependent {};

template<>
struct Dependent<A> {
    using type = B;
};

template<>
struct Dependent<C> {
    using type = D;
};


template <typename Type>
class ClassName {
    using Dependent = typename Dependent<Type>::type;
};

int main()
{
    static_assert(std::is_same<Dependent<A>::type, B>::value, "");
    static_assert(std::is_same<Dependent<C>::type, D>::value, "");
    // Dependent<B>::type a;    error: 'type' is not a member of 'Dependent<B>'  
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-31
    • 2013-03-26
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多