SFINAE: decltype для оператора []

На основе ответов здесь и здесь я пытаюсь использовать следующее

template <typename T>
using operator_square_brackets = decltype(&T::operator[]);

Это терпит неудачу на визуальной студии с

error C2760: syntax error: expected ')' not ']'

Любые идеи о том, как это исправить?

1 ответ

Решение

Если вы хотите определить, имеет ли тип определенную функцию или перегруженный оператор, вы должны вызвать эту функцию или оператор. Это важно, потому что у вас может быть несколько перегрузок функции или оператора, и разрешение перегрузки всегда зависит от вызывающей стороны.

Вот небольшой пример, основанный на CppCon 2014: Уолтер Э. Браун "Метапрограммирование современных шаблонов: сборник, часть II" о том, как обнаружить operator[] в виде.

Я понятия не имею, почему VC выдает такую ​​странную ошибку, которая больше похожа на ошибку синтаксического анализа. Я ожидал, что что-то вроде "ссылка на перегруженную функцию не может быть решена; ты хотел это назвать?

#include <string>
#include <type_traits>
#include <vector>

// in C++17 std::void_t
template < typename... >
using void_t = void;


template < typename T, typename Index >
using subscript_t = decltype(std::declval<T>()[std::declval<Index>()]);

template < typename, typename Index = size_t, typename = void_t<> >
struct has_subscript : std::false_type {};

template < typename T, typename Index >
struct has_subscript< T, Index, void_t< subscript_t<T,Index> > > : std::true_type {};


struct A
{
  void operator[](size_t) {}
};

struct B {};

int main ()
{
  static_assert(has_subscript< std::vector<int> >::value    == true , "!");
  static_assert(has_subscript< std::vector<double> >::value == true , "!");
  static_assert(has_subscript< A >::value                   == true , "!");
  static_assert(has_subscript< A, std::string >::value      == false, "!");
  static_assert(has_subscript< B >::value                   == false, "!");
  static_assert(has_subscript< double[5] >::value           == true , "!");
  static_assert(has_subscript< double* >::value             == true , "!");
  static_assert(has_subscript< double >::value              == false, "!");
}
Другие вопросы по тегам