2017-07-21 18 views
8

Dựa trên câu trả lời herehere Tôi cố gắng để sử dụng sau đâySFINAE: decltype trên operator []

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

Nó không thành công trên visual studio với

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

Bất kỳ ý tưởng về làm thế nào để sửa lỗi này ?

+1

Phiên bản nào, không quan tâm? – Bathsheba

+2

2017 64 bit ... – Cookie

+2

Sử dụng từ chối và sau đó lập chỉ mục theo cách thủ công có hoạt động không? 'template using operator_square_brackets = decltype (std :: declval () [std :: declval ()]);' –

Trả lời

8

Nếu bạn muốn phát hiện xem loại có chức năng nhất định hoặc toán tử quá tải, bạn phải gọi hàm hoặc toán tử đó. Điều này rất quan trọng vì bạn có thể có một số tình trạng quá tải của một hàm hoặc toán tử và độ phân giải quá tải luôn phụ thuộc vào người gọi.

Dưới đây là một ví dụ nhỏ, dựa trên CppCon 2014: Walter E. Brown "Modern Template Metaprogramming: A Compendium, Part II" về cách phát hiện operator[] trong một loại.

Tôi không biết tại sao VC lại cho bạn một lỗi lạ như vậy trông giống như lỗi phân tích cú pháp. Tôi đã có thể mong đợi một cái gì đó như »tham chiếu đến chức năng quá tải không thể được giải quyết; Ý bạn là gọi nó là gì?

#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, "!"); 
} 
+6

[is_detected] (https://stackoverflow.com/documentation/c%2b%2b/1169/sfinae-substitution-failure-is-not-an-error/18585/is-detected#t=201707210748041399684) có thể bạn quan tâm khái quát khái niệm. – Jarod42

+3

'std :: map ' sẽ là một ví dụ tốt cho 'Index' không phải là' size_t'. – Jarod42

+0

Nếu bạn không sử dụng tham số thông báo lỗi của 'static_assert', bạn có thể bỏ qua nó. – Rakete1111