How can I check the type of a template parameter in C ++?
2 answers
It seems to me that you want something like this:
template <class T>
std::enable_if_t<std::is_base_of<SomeInterface, T>::value, void>
genericMethod(std::set<T> tSet)
{
// Do something
}
If you can clarify what it means Set<? extends T> tSet
, then I'm sure we can include that as well.
+4
source to share
You can do this in one of two ways, the simplest solution here is to use a base class pointer that represents the interface. After this point, you can only pass pointers to objects derived from this base class. So something like this
#include <iostream>
#include <string>
using std::cout;
using std::endl;
class BaseOne {};
class BaseTwo {};
class DerivedOne : public BaseOne {};
class DerivedTwo : public BaseTwo {};
void foo(BaseOne*) {
cout << __PRETTY_FUNCTION__ << endl;
}
void foo(BaseTwo*) {
cout << __PRETTY_FUNCTION__ << endl;
}
int main() {
auto derived_one = DerivedOne{};
auto derived_two = DerivedTwo{};
foo(&derived_one);
foo(&derived_two);
}
Or, if the goal is to do it at compile time without base classes, that is, without inheritance and without concepts (which are expected to come out in C ++ 20 ¯ \ _ (ツ) _ / ¯), and only check for some methods, then you can do something like this
#include <iostream>
#include <type_traits>
using std::cout;
using std::endl;
struct One { void one() {} };
struct Two { void two() {} };
/**
* Loose SFINAE based concepts
*/
template <typename Type, typename T = std::decay_t<Type>>
using EnableIfOne = std::enable_if_t<std::is_same<
decltype(std::declval<T>().one()), decltype(std::declval<T>().one())>
::value>;
template <typename Type, typename T = std::decay_t<Type>>
using EnableIfTwo = std::enable_if_t<std::is_same<
decltype(std::declval<T>().two()), decltype(std::declval<T>().two())>
::value>;
template <typename T, EnableIfOne<T>* = nullptr>
void foo(T&) {
cout << __PRETTY_FUNCTION__ << endl;
}
template <typename T, EnableIfTwo<T>* = nullptr>
void foo(T&) {
cout << __PRETTY_FUNCTION__ << endl;
}
int main() {
auto one = One{};
auto two = Two{};
foo(one);
foo(two);
}
+1
source to share