简体   繁体   English

模板化运算符[] ......可能吗? 有用?

[英]Templated operator[]… possible? Useful?

Could you have: 你能拥有:

template <class T>
const T &operator[] (unsigned int x)

My thinking was if you have a map<string,string> it would be nice to have a wrapper class which lets you do: 我的想法是,如果你有一个map<string,string> ,那么拥有一个包装类可以让你做到:

obj["IntVal"]="12";
obj["StringVal"]="Test";

int i = obj["IntVal"];

How close to this can we actually get in C++? 我们实际上可以在C ++中接近这一点吗? Is it worth the pain? 值得痛苦吗?

You can also do 你也可以

class Class {
  struct Proxy {
    template<typename T> T as() { ... }
    template<typename T> operator T() { return as<T>(); }
  private:
    Proxy(...) { ... }
    Proxy(Proxy const&); // noncopyable
    Proxy &operator=(Proxy const&);
    friend class Class;
  };

public:
  Proxy operator[](std::string const& s) { ... }
};

Class a;
int i = a["foo"];
int i = a["foo"].as<int>();

T will be deduced to whatever the to be initialized object is. T将被推导为要初始化的对象。 And you are not allowed to copy the proxy. 并且您不能复制代理。 That said, i prefer an explicit as<T> function like another one proposed too. 也就是说,我更喜欢一个明确的as<T>函数,就像另一个提议的那样。

You can't - in: 你不能 - 在:

int i = obj["IntVal"]; 

the actual type of T can't be inferred from the context since the return type isn't part of the function signature. 由于返回类型不是函数签名的一部分,因此无法从上下文中推断出T的实际类型。

Moreover, storing integer values as strings is not considered as best practices, due to memory and performance considerations ;-) 此外,由于内存和性能方面的考虑,将整数值存储为字符串不被视为最佳实践;-)

Not worth it. 不值得。

Templating the return type means you'd have to explicitly specify the template parameter when you call it. 模板返回类型意味着您在调用模板参数时必须明确指定模板参数。 Something like this, maybe I have the syntax wrong: 像这样的东西,也许我的语法错了:

int i = obj.operator[]<int>("IntVal");

C++ does not deduce template parameters from what you assign the result of the call to, only from the parameters you call the function with. C ++不会从您分配调用结果的内容中推导出模板参数,只能从调用函数的参数中推导出模板参数。

So you might as well just define a normal function: 所以你不妨定义一个正常的函数:

int i = obj.get<int>("IntVal");

Or in this case, either do this or implement get using this: 或者在这种情况下,要么这样做,要么实现get使用:

int i = boost:lexical_cast<int>(obj["IntVal"]);

As Amit says, you could define operator[] to return a type which can be converted either to int or to other types. 正如Amit所说,你可以定义operator[]来返回一个可以转换为int或其他类型的类型。 Then your example code can be made to compile without the explicit lexical_cast. 然后您的示例代码可以在没有显式lexical_cast的情况下进行编译。

Have you looked at boost variant ? 你看过boost变种吗? Is this what you're looking for? 这是你在找什么?

Well, what you wrote in your sample code doesn't match the question. 那么,你在示例代码中写的内容与问题不符。 Right now, you only have the return type templated. 现在,您只有模板化的返回类型。

But if you wanted to do something like: 但如果你想做一些像:

template <class T>
const T &operator[const T& x]

that's valid, though maybe not terribly useful. 这是有效的,虽然可能不是非常有用。

A map already provides an overloaded operator[] that does most of what you want. 地图已经提供了一个重载的operator[] ,可以完成您想要的大部分operator[] The thing you seem to want that's missing is implicit conversion from a string that happens to contain digits to an integer. 你似乎想要的东西是从一个恰好包含数字的字符串到一个整数的隐式转换。 One of the fundamental characteristics of C++ is static typing, which says that shouldn't be allowed -- so it's not. C ++的一个基本特征是静态类型,它表示不应该允许 - 所以它不是。 It'll be happy to do that conversion if you want, but you'll have to ask for it: 如果你愿意,它会很高兴做到这种转换,但你必须要求它:

int i = lexical_cast<int>(obj["IntVal"]);

Alternatively, you could create a string-like class that supported implicit conversion to int . 或者,您可以创建一个类似字符串的类,支持隐式转换为int Personally, I'd advise against that. 就个人而言,我建议不要这样做。 I don't object to implicit conversions nearly as strongly as many people do, but that still strikes me as a pretty lousy idea, at least for most general use. 我并不反对隐含的转换几乎与许多人一样强烈,但这仍然让我觉得这是一个非常糟糕的想法,至少对于大多数一般用途而言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM