In the code below, Foo<T>::setValue
works well for my purposes, except in cases where where T
is a class enum named TYPE
e.g. Bar::TYPE
and Baz:TYPE
.
Therefore, I'd appreciate help specializing Foo<T>::setValue
without naming Bar
and Baz
, because there could be dozens of such classes.
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;
}
You can do this with something like:
#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;
};
Where enable_if
picks which version to use based on the is_enum
type trait.
The example used C++11 enable_if
and is_enum
but boost has similar for pre-C++11 also.
Consider this:
#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;
}
来源:https://stackoverflow.com/questions/10552255/specializing-member-template-for-enum-type-arguments