【问题标题】:Specialize template according to the value of an enum member根据枚举成员的值专门化模板
【发布时间】:2014-05-22 18:34:50
【问题描述】:

我想根据它所操作的类的枚举成员来专门化模板函数成员的行为。我很确定这是可行的,但我不知道怎么做。这是一个无法编译的失败尝试(为什么?)。事实上,我已经为我的项目找到了一个可行的解决方案(使用继承),但这并不好,我很好奇可以做什么。

#include <iostream>

struct A
{
    enum
    {
        Size = 2    
    };
};

struct B
{
    enum
    {
        Size = 3
    };
};

template <int I>
struct EnumToType
{
    static const int e = I;
};

template <typename T, typename U>
struct C {};

template <typename T>
struct D
{
    typedef C<T, typename EnumToType<T::Size> > Type;
};

template <typename T>
struct C<T, EnumToType<2> >
{
    void operator()()
    {
        std::cout << "hi !" << std::endl;
    }    
};

template <typename T>
struct C<T, EnumToType<3> >
{
    void operator()()
    {
        std::cout << "hello !" << std::endl;
    }    
};

int main()
{
    D<A>::Type da;
    D<B>::Type db;
    da();
    db();
    return 0;
}

一个有用的link...

【问题讨论】:

标签: c++ templates enums


【解决方案1】:
typedef C<T, typename EnumToType<T::Size> > Type;

这里的typename关键字无意义且非法,去掉即可。

【讨论】:

  • 我删除了它并且它有效。谢谢 !有没有更好的 c++03 方法来实现我想要的?
  • 我不明白你为什么需要 EnumToType,可能只是直接使用这些值。除此之外,不,我没有看到任何不好的地方。
  • 又成功了!我认为它不起作用,因为我最后给出的链接(以及构造函数给出的链接)但是这个伪模板类型定义不是部分模板专业化(显然)所以它工作。 :-)
【解决方案2】:

一般模式如下(使用bool 类型而不是enum 类型,但原理保持不变):

template<typename FalseType, typename TrueType, bool condition> 
struct ConditionalTypeSelector {
    typedef void ResultType;
};

template<typename FalseType, typename TrueType>
struct ConditionalTypeSelector<FalseType,TrueType,false> {
    typedef FalseType ResultType;
};

template<typename FalseType, typename TrueType>
struct ConditionalTypeSelector<FalseType,TrueType,true> {
    typedef TrueType ResultType;
};

在其他地方使用它

ConditionalTypeSelector<A,B,(sizeof(A) > sizeof(B))>::ResultType

【讨论】:

  • 感谢您花时间回答我的问题,但这不是相同的模式。您的示例只是模板专业化,条件不依赖于 A 或 B 静态 const 成员......或者我误解了一些东西。
  • @matovitch 我从我的blog entry 中快速获取了这个样本。 ConditionalTypeSelector 类可以很容易地使用您建议的枚举类型而不是 bool 条件,并且当然对枚举值有更多的专业化。我仍然认为这是相同的模式。
【解决方案3】:

我不得不质疑你想要达到什么目的,但这是解决你的例子的一种方法:

struct A
{
    static const int Size = 2;
};

struct B
{
    static const int Size = 3;
};

template<int message_id>
struct Message;

template<>
struct Message<2>
{
    void operator()()
    {
        std::cout << "hi !" << std::endl;
    }    
};

template<>
struct Message<3>
{
    void operator()()
    {
        std::cout << "hello !" << std::endl;
    }
};

template<typename T>
struct SizeStructToMessage
{
    void operator()()
    {
        Message<T::Size> msg;
        msg();
    }
};

int main()
{
    SizeStructToMessage<A> a;
    SizeStructToMessage<B> b;
    a();
    b();
    return 0;
}

【讨论】:

  • 是的,它是相同的模式。如果你有电话接线员,typedef 或其他什么都没有关系。对于操作员的问题,他希望使用枚举而不是 int 来执行此操作,但这几乎可以归结为同一件事。
  • @Curg 我正在使用提升方案实现一个用于离散小波变换的库。我特别使用模板来展开循环。在这种情况下,我想实现 ApplyForward 和 ApplyReverse 仿函数,如果要应用的提升是原始的或双重的,它们不应该表现出相同的行为(因为我使用的是特征类,使用继承意味着将它们移回别名更多样板: /)。
猜你喜欢
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多