I have a traits class like the following that reflects the compatibility between two types:
template <typename ObjectType, typename ArgumentType>
struct Traits
{
static const bool SpecialMethodAvailable = false;
};
The single member determines if SpecialMethod()
can be called on objects of type ObjectType
with argument of type ArgumentType
.
A simple class that supports this is the following:
class ClassWithSpecialMethod
{
public:
template <typename T>
void SpecialMethod(T param) { std::cout << "Special Method called with " << param << std::endl; }
};
template <typename ArgumentType>
struct Traits<ClassWithSpecialMethod, ArgumentType>
{
static const bool SpecialMethodAvailable = true;
};
I want to write a worker class that uses this traits class and calls the special method if it is available. Basically something like the following:
template <typename T>
struct Worker
{
static void DoSomething(T t, GlobalDataType& globalData)
{
//if Traits<GlobalDataType, T>::SpecialMethodAvailable
// call the method
//else
// do something different
}
};
I tried to realize this using std::enable_if
. My solution works with the Visual C 14.1 compiler but not with GCC. Here is what I tried:
template <typename T, typename Enable = void>
struct Worker
{
static void DoSomething(T t, GlobalDataType& globalData)
{
std::cout << "There is no special method (called with " << t << ")" << std::endl;
}
};
template <typename T>
struct Worker<T, typename std::enable_if<Traits<GlobalDataType, T>::SpecialMethodAvailable>::type>
{
static void DoSomething(T t, GlobalDataType& globalData)
{
globalData.SpecialMethod(t);
}
};
I used this as follows:
typedef ... GlobalDataType; //before the template declarations
int main()
{
GlobalDataType td;
int integer = 0;
Worker<int>::DoSomething(integer, td);
}
If GlobalDataType
is typedef'ed to ClassWithSpecialMethod
, both VS and GCC compile fine and output correctly:
Special Method called with 0
However, if GlobalDataType
is typedef'ed to something that does not allow the special method (e.g. int
), VS still produces the correct output while GCC results in a compile error:
In static member function ‘static void Worker::SpecialMethodAvailable>::type>::DoSomething(T, GlobalDataType&)’: source.cpp:38:15: error: request for member ‘SpecialMethod’ in ‘globalData’, which is of non-class type GlobalDataType {aka int}’
Can someone explain why this does not work as intended under GCC? What would be alternatives?
Aucun commentaire:
Enregistrer un commentaire