This is my simplified code :
template<typename device, template<typename device> class protocol>
class MyClass
{
public:
template<typename select>
bool method()
{
// Code
}
};
I want method
to act different in terms of the protocol
type.
In other words, I have two different possible protocols, and I want to have two different behaviours for my method according to the protocols. But I don't know how to write it with templates.
By example, using SFINAE (if you accept a C++11 solution)
#include <iostream>
#include <type_traits>
template <typename>
struct protocol_1
{ };
template <typename>
struct protocol_2
{ };
template<typename device, template<typename> class protocol>
class MyClass
{
public:
template<typename select, typename p = protocol<device>>
typename std::enable_if<
std::is_same<p, protocol_1<device>>::value, bool>::type
method()
{ return true; }
template<typename select, typename p = protocol<device>>
typename std::enable_if<
std::is_same<p, protocol_2<device>>::value, bool>::type
method()
{ return false; }
};
int main()
{
MyClass<int, protocol_1> m1;
MyClass<int, protocol_2> m2;
std::cout << m1.method<int>() << std::endl; // print 1 (true)
std::cout << m2.method<void>() << std::endl; // print 0 (false)
}
--- EDIT ---
As pointed by Yakk (thanks!), this solution is weak because use a template default value that can be explicited and circunvented.
An example; with
MyClass<int, protocol_1>{}.method<void>();
is called the "protocol_1" version of method()
, using the default value for p
; but explciting p
, as follows
MyClass<int, protocol_1>{}.method<void, protocol_2<int>>();
is called the "protocol_2" version of method()
over an istance of a MyClass
based on protocol_1
To avoid this problem it's possible add a static_assert()
, in both version of method()
, to check and impose that p
is equal to its default value (protocol<device>
)
I mean... as follow
template<typename select, typename p = protocol<device>>
typename std::enable_if<
std::is_same<p, protocol_1<device>>::value, bool>::type
method()
{
static_assert(std::is_same<p, protocol<device>>::value, "!");
return true;
}
template<typename select, typename p = protocol<device>>
typename std::enable_if<
std::is_same<p, protocol_2<device>>::value, bool>::type
method()
{
static_assert(std::is_same<p, protocol<device>>::value, "!");
return false;
}
So
MyClass<int, protocol_1>{}.method<void, protocol_2<int>>();
generate a compiler error.