Как определить, применим ли оператор [] к типу?

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

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

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


person kyb    schedule 01.05.2016    source источник
comment
Что плохого в том, чтобы просто писать код как есть?   -  person T.C.    schedule 01.05.2016
comment
Ничего страшного, но если возможно, я хочу ограничить неправильные типы.   -  person kyb    schedule 01.05.2016
comment
@kyb Что ж, они будут ограничены (если вы не хотите исключить типы простых указателей). Вы хотите улучшить сообщения об ошибках?   -  person πάντα ῥεῖ    schedule 01.05.2016
comment
Каким должен быть результат, если кто-то позвонит foo(1)? Как написано, это ошибка времени компиляции, которая на первый взгляд является правильным ответом.   -  person Pete Becker    schedule 01.05.2016
comment
Вы правы, но я искал что-то вроде ответа T.C. Спасибо   -  person kyb    schedule 01.05.2016


Ответы (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.

person T.C.    schedule 01.05.2016

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

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

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

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

person FedeWar    schedule 01.05.2016