1

I would like to write function template like

template< typename T >
void foo( T& obj ){
    obj[0] = xxxxxx;
}

where T must have operator[] applicable.
T may be array of any type, std::vector, std::array, or any other type. So, I cannot use T as superclass of all of them. I think it should be something like in std::type_traits style.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
kyb
  • 7,233
  • 5
  • 52
  • 105

2 Answers2

3
template<class T>
using LvalueIndexable = decltype(std::declval<T&>()[1]);

template<class T, class U = void>
using RequiresLvalueIndexable 
    = typename std::enable_if<std::experimental::is_detected<LvalueIndexable, T>{},
                              U>::type;

template< typename T, typename = RequiresLvalueIndexable<T> >
void foo( T& obj ){
    obj[0] = xxxxxx;
}

See the cppreference page for how to implement std::experimental::is_detected.

T.C.
  • 133,968
  • 17
  • 288
  • 421
1

There are several ways to restrict template types:

1) declare the function template as a private class method and then call it from public overloaded methods, as described here;

2) using Boost static assert and is_base_of to compare template and types, see here;

3) or include type_traits and use asserts static_assert(is_same<T, float>::value, "Error message");

Community
  • 1
  • 1
FedeWar
  • 537
  • 1
  • 7
  • 17