Я хотел бы написать шаблон функции, например

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

Где T должен иметь применимый оператор [].
T может быть массивом любого типа, std :: vector, std :: array или любого другого типа. Итак, я не могу использовать T как суперкласс всех из них. Я думаю, это должно быть что-то вроде стиля std :: type_traits.

1
kyb 1 Май 2016 в 09:32

2 ответа

Лучший ответ
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;
}

См. страницу cppreference, чтобы узнать, как реализовать std::experimental::is_detected.

3
T.C. 1 Май 2016 в 06:55

Есть несколько способов ограничить типы шаблонов:

1) объявить шаблон функции как метод частного класса, а затем вызвать его из общедоступных перегруженных методов, как описано в здесь;

2) использование статического утверждения Boost и is_base_of для сравнения шаблона и типов, см. здесь;

3) или включить type_traits и использовать утверждения static_assert(is_same<T, float>::value, "Error message");

1
Community 23 Май 2017 в 12:07