3

I'm trying to check if operator [] overloaded in some class. There is my code:

template <class T, class = void>
struct has_operator : std::false_type {};

template <class T>
struct has_operator < T,
            std::void_t<decltype(std::declval<T>[](int i))>> :
            std::true_type {};

But it doesn't work actualy.

I'm trying to write like code witch cheking if class has operator ()

here it's :

template <typename T,class=void>
struct callable_without_args: std::false_type{};

template <typename T>
struct callable_without_args<T
          ,std::void_t<decltype(std::declval<T>()())>>
  :std::true_type{};

Ok, This code compiles, but how to do the verification exactly in main?:


template <class T, class = void>
struct has_operator : std::false_type {};

template <class T>
struct has_operator < T,
            std::void_t<decltype(std::declval<T>()[0])>> :
            std::true_type {};

I did it!

#include <type_traits>
#include <tuple>
#include <vector>


template <class T, class = void>
struct has_operator : std::false_type {};

template <class T>
struct has_operator < T,
            std::void_t<decltype(std::declval<T>()[0])>> :
            std::true_type {};


struct T {
    int* arr;
    T(int a) {
        arr = new int[a];
    }
    const int& operator [] (int i) {
        return arr[i];
    }
};

int main() {
    bool test = has_operator<T>::value;

    test == true ? std::cout << "yes" : std::cout << "no";
}

Kabanich
  • 33
  • 4

1 Answers1

3

Not completely clear what do you exactly want but... the following decltype() is wrong

// ---------------------VVVVVVVVV   Wrong
decltype(std::declval<T>[](int i))

std::declval() is a (declared only) function, that doesn't receive arguments.

That is: you have to "call" it, adding "()" after "<T>".

I suppose you can try with something as

// .....................VV  call std::declval   
decltype(std::declval<T>()[0])
// .......................^^^  and invoke operator [] over the retuned object

This should works when the operator[] of the class T accept a integer value.

If operator[] doesn't accept a integer value (by example: a std::map with a key incompatible with int) but want a value of another type, say type U, you can try with another std::declval()

// ........................VVVVVVVVVVVVVVVVV   U value
decltype(std::declval<T>()[std::declval<U>()])
max66
  • 65,235
  • 10
  • 71
  • 111
  • @КириллВахрамян - you should show us a minimal but complete and compilable example; otherwise we can show some errors but it's difficult to propose a working solution. – max66 Jan 08 '20 at 10:19