2

在下面的代码中,Foo<T>::setValue对于我的目的来说效果很好,除非在 whereT是一个名为TYPEegBar::TYPE和的类枚举Baz:TYPE

Foo<T>::setValue因此,如果没有命名Barand ,我会很感激专业帮助Baz,因为可能有几十个这样的类。

class Bar
{
public:
    enum TYPE{ ONE , TWO };
};

class Baz
{
public:
    enum TYPE{ SIX , TEN };
};

template<typename T>
class Foo
{
public:
    void setValue(){} // Need a different setValue if T is a class enum

private:
    T m_value;
};


int main()
{
    Foo<int> f1;
    Foo<Bar::TYPE> f2;
    Foo<Baz::TYPE> f3; 
    return EXIT_SUCCESS;
}
4

2 回答 2

6

你可以这样做:

#include <type_traits>

template<typename T>
class Foo
{
public:
    void setValue() {
      setValueImpl<T>();
    }
private:
    template <class X>
    typename std::enable_if<std::is_enum<X>::value, void>::type
    setValueImpl() { std::cout << "Is enum" << std::endl; }

    template <class X>
    typename std::enable_if<!std::is_enum<X>::value, void>::type
    setValueImpl() { std::cout << "Not enum" << std::endl; } 

    T m_value;
};

Whereenable_if根据is_enum类型特征选择要使用的版本。

该示例使用了 C++11 enable_ifis_enum但是对于 pre-C++11,boost 也有类似的情况。

于 2012-05-11T13:51:44.210 回答
1

考虑一下:

#include <iostream>

class Bar
{
public:
    enum TYPE{ ONE , TWO };
};

class Baz
{
public:
    enum TYPE{ SIX , TEN };
};

template<typename T>
class Foo
{
public:
    template<typename C> void setValue(const C &m_value, ...) 
    {
        std::cout << "normal" << std::endl;
    }

    template<typename C> void setValue(const C &m_value, typename C::TYPE fake = C::TYPE()) 
    {
        std::cout << "TYPE'ed" << std::endl;
    }

private:
    T m_value;
};


int main()
{
    Foo<int> f1;
    Foo<Bar> f2;
    Foo<Baz> f3; 

    f1.setValue(1);
    f2.setValue(Bar());
    f3.setValue(Baz());

    return 0;
}
于 2012-05-11T13:46:29.127 回答