SFINAE:运算符[]上的decltype

Coo*_*kie 8 c++ sfinae visual-studio

根据这里这里的答案,我试图使用以下

template <typename T>
using operator_square_brackets = decltype(&T::operator[]);
Run Code Online (Sandbox Code Playgroud)

它在视觉工作室失败了

error C2760: syntax error: expected ')' not ']'
Run Code Online (Sandbox Code Playgroud)

有想法该怎么解决这个吗?

Hen*_*nke 8

如果要检测类型是否具有某个函数或重载运算符,则必须调用该函数或运算符.这很重要,因为您可能有多个函数或运算符重载,并且重载决策总是取决于调用者.

这是一个基于CppCon 2014的小例子:Walter E. Brown"现代模板元编程:概要,第二部分",关于如何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, "!");
}
Run Code Online (Sandbox Code Playgroud)

  • [is_detected](https://stackoverflow.com/documentation/c%2b%2b/1169/sfinae-substitution-failure-is-not-an-error/18585/is-detected#t=201707210748041399684)您可能会对此感兴趣概括了这个概念. (6认同)
  • `std :: map <std :: string,int>`将是一个不是`size_t`的`Index`的好例子. (3认同)