Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Templates: Only execute method if class has it

I want to write a function which executes the method of some templated class, but should also compile fine if the class doesn't have it. In that case, it should just not call the function.

struct A
{
   void func() {}
};

struct B
{
};

template <typename T>
void anotherFunc(T t)
{
   //do t.func() here if T implements func, just do nothing if it doesn't.
}

Is this possible somehow?

like image 516
TravisG Avatar asked May 01 '14 19:05

TravisG


People also ask

How will you restrict the template for a specific datatype?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.

Can templates be used for classes?

Templates in c++ is defined as a blueprint or formula for creating a generic class or a function. To simply put, you can create a single function or single class to work with different data types using templates. C++ template is also known as generic functions or classes which is a very powerful feature in C++.

What is the difference between template class and template function?

For normal code, you would use a class template when you want to create a class that is parameterised by a type, and a function template when you want to create a function that can operate on many different types.

Can a template class have more than one generic data type?

Explanation: The template class can support more than one data type. The only thing is to add all the data types required in a list separated by comma within template specification. 2. Which among the following is the proper syntax for the template class?

What is the use of class template?

Class Templates Like function templates, class templates are useful when a class defines something that is independent of the data type. Can be useful for classes like LinkedList, BinaryTree, Stack, Queue, Array, etc.

How to use multiple template parameters in C++?

In C++, we can use multiple template parameters and even use default arguments for those parameters. For example, template <class T, class U, class V = int> class ClassName { private: T member1; U member2; V member3; ... .. ... public: ... .. ...

What can be explicitly instantiated from a class template?

Classes, functions, variables, and member template specializations can be explicitly instantiated from their templates. Member functions, member classes, and static data members of class templates can be explicitly instantiated from their member definitions. Explicit instantiation can only appear in the enclosing namespace of the template, ...

What are some examples of templates in C++?

Examples of function templates are sort (), max (), min (), printArray (). Below is the program to implement Bubble Sort using templates in C++: Class Templates Like function templates, class templates are useful when a class defines something that is independent of the data type.


1 Answers

// type_sink takes a type, and discards it.  type_sink_t is a C++1y style using alias for it
template<typename T> struct type_sink { typedef void type; };
template<typename T> using type_sink_t = typename type_sink<T>::type;

// has_func is a traits class that inherits from `true_type` iff the expression t.func()
// is a valid one.  `std::true_type` has `::value=true`, and is a good canonical way to
// represent a compile-time `bool`ean value.
template<typename T,typename=void> struct has_func : std::false_type {};
template<typename T> struct has_func<
  T,
  type_sink_t< decltype( std::declval<T&>().func() ) >
> : std::true_type {};

// helpers for tag dispatching.
namespace helper_ns {
  template<typename T> void anotherFunc( T&& t, std::false_type /* has_func */ ) {}
  template<typename T> void anotherFunc( T&& t, std::true_type /* has_func */ ) {
    std::forward<T>(t).func();
  }
}
// take the type T, determine if it has a .func() method.  Then tag dispatch
// to the correct implementation:
template<typename T> void anotherFunc(T t) {
  helper_ns::anotherFunc( std::forward<T>(t), has_func<T>() );
}

is a C++11 solution that does tag dispatching on a traits class that determines if t.func() is a valid expression.

like image 174
Yakk - Adam Nevraumont Avatar answered Oct 23 '22 03:10

Yakk - Adam Nevraumont