如何调用模板数组运算符重载函数?

How do I call template array operator overloading function?

我需要创建一个适配器 C++ class,它接受一个整数索引,并通过索引从 C 模块中检索某些类型的数据,然后 returns 它到 C++ 模块.

C模块中的数据检索函数如下:

int getInt(int index);
double getDouble(int index);
const char* getString(int index);
// ...and etc.

我想为 C++ 模块实现一个类似数组的接口,所以我创建了以下 class:

class Arguments {
public:
    template<typename T> T operator[] (int index);
};

template<> int Arguments::operator[] (int index) { return getInt(index); }
template<> double Arguments::operator[] (int index) { return getdouble(index); }
template<> std::string Arguments::operator[] (int index) { return getString(index); }

(模板class在这种情况下没有帮助,但只有模板成员函数)

适配器 class 没什么大不了的,但是调用 Arguments::operator[] 是个问题!

我发现只能这样调用:

Arguments a;
int i = a.operator[]<int>(0);       // OK
double d = a.operator[]<double>(1); // OK

int x = a[0];                       // doesn't compile! it doesn't deduce.

但这看起来像个笑话,不是吗?

如果是这样的话,我宁愿创建普通的成员函数,比如template<T> T get(int index)

那么问题来了:如果我创建数组运算符重载函数 T operator[]() 及其特化,是否可以像访问数组一样调用它?

谢谢!

简单的回答是:不,不可能。您不能根据其 return 类型重载函数。在这里查看类似的问题:overload operator[] on return type

但是,有一个技巧可以让您从赋值的 lhs 中推导出类型:

#include <iostream>
#include <type_traits>

struct container;
struct helper {
    container& c;
    size_t index;
    template <typename T> operator T();
};

struct container {
    helper operator[](size_t i){
        return {*this,i};
    }
    template <typename T> 
    T get_value(size_t i){
        if constexpr (std::is_same_v<T,int>) {
            return 42;
        } else {
            return 0.42;
        }
    }
};

template <typename T> 
helper::operator T(){
    return c.get_value<T>(index);
}

int main() {
    container c;
    int x = c[0];
    std::cout << x << "\n";
    double y = c[1];
    std::cout << y ;
}

输出为:

42
0.42

int x = c[0]; 通过 container::get_value<int>,其中 int 是从 x 的类型推导出来的。同样 double y = c[1]; 使用 container::get_value<double> 因为 ydouble.

你付出的代价是大量的样板和使用 auto 这样的

auto x = c[1];

会给你一个 helper,而不是你想要的值,这可能有点出乎意料。