我想实施以下课程:
class A
{
public:
template<typename VAL_TYPE>
class PP {
public:
PP();
void init(const string &name);
operator VAL_TYPE();
VAL_TYPE & operator = (const VAL_TYPE&);
private:
string _name;
VAL_TYPE _val;
void getter();
void setter();
};
A();
public:
template<typename VAL_TYPE>
PP<VAL_TYPE>& operator[](const string& name);
private:
PP<int> _pp_int;
PP<double> _pp_float;
PP<string> _pp_string;
};
getter
和setter
方法在.cpp文件中实现,用于&#39; int&#39;,&#39; double&#39;和&#39;字符串&#39;类型分开:
void A::PP<int>::setter()
{
...
}
void A::PP<int>::getter()
{
...
}
以及&#39; double&#39;等等和&#39;字符串&#39;类型。
问题是关于重载的A :: operator []。
它应该返回P<int>
(_pp_int成员)或PP<double>
(_pp_float成员)或PP<string>
(_pp_string成员)
名称&#39;的价值参数。目的是使用这样的东西:
A a;
a["iii"] = 10;
int i = a["iii"];
a["ddd"] = 3.141519;
double d = a["ddd"];
a["sss"] = "string";
string s = a["sss"];
据我所知,这是一个大问题:编译器如何在A :: operator []中推导出模板参数VAL_TYPE
。
有可能实现这样的想法吗? 我阅读了很多帖子,但仍然找不到任何解决方案。
可能在Qt库的框架中可以吗?
答案 0 :(得分:1)
你最容易接近的是:
#include <boost/variant.hpp>
#include <string>
#include <unordered_map>
using Map = std::unordered_map<std::string, boost::variant<std::string, int, double> >;
int main()
{
Map m;
m["iii"] = 5;
int i = boost::get<int>(m["iii"]);
m["ddd"] = 0.3;
double d = boost::get<double>(m["ddd"]);
m["sss"] = "hello";
std::string s = boost::get<std::string>(m["sss"]);
return 0;
}
此代码可以运行并执行您想要的操作。 boost变量是一个“sum”类型,它只包含一个对象,它具有模板化的一种类型。换句话说,这里它们包含字符串,整数或双精度。
当赋予boost变量时,它将根据指定的类型进行类型推断并执行正确的操作。但它没有办法轻松地为所有类型提供隐式转换。所以你必须明确提取值。坦率地说,我建议只是按原样使用它并与它一起生活,但我确定你没有听到这样的消息,所以...
在您的特定情况下,如果您愿意放弃通用性,则可以执行此操作。基本上,您只需编写一个包含boost变体的类,但您也可以为其添加隐式转换。
class PP {
public:
// forward heterogeneous assignment etc so that works as before
operator std::string() { return boost::get<string>(m_data); }
// similar for other types
private:
boost::variant<std::string, int, double> m_data;
}
现在,当您尝试将PP
分配给字符串时,将没有直接赋值,但编译器将看到PP
提供了对字符串的隐式转换并使用它。 / p>
问题是,这在语言复杂性方面打开了一大堆蠕虫,并不值得。它应该实际上是通过引用提供转换,通过引用,关于constness,rvalues等等。还有值得考虑的是boost::get
如果变量不包含所请求的类型,将非常大声地(通过抛出)失败,所以你现在有一种情况,无辜的分配操作很容易抛出。我建议学习一下boost变体(它可能会很快成为标准的一部分,它已被大量讨论)并学习了一些在那里使用的技术,比如访问者。它们起初可能是外来的,但是它们工作得很好,它们发挥C ++的优势,而不是试图让C ++表现得像python。