如何调用模板数组运算符重载函数?
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>
因为 y
是 double
.
你付出的代价是大量的样板和使用 auto
这样的
auto x = c[1];
会给你一个 helper
,而不是你想要的值,这可能有点出乎意料。
我需要创建一个适配器 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>
因为 y
是 double
.
你付出的代价是大量的样板和使用 auto
这样的
auto x = c[1];
会给你一个 helper
,而不是你想要的值,这可能有点出乎意料。