gpt4 book ai didi

c++ - 返回模板类中的模板参数推导

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:12:56 25 4
gpt4 key购买 nike

我想实现以下类:

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;
};

gettersetter方法在 .cpp 文件中分别针对 'int'、'double' 和 'string' 类型实现:

void A::PP<int>::setter()
{
...
}
void A::PP<int>::getter()
{
...
}

对于 'double' 和 'string' 类型依此类推。

问题是关于重载的 A::operator[]。它应该返回 P<int> (_pp_int 成员)或 PP<double> (_pp_float 成员)或 PP<string> (_pp_string 成员) 根据“名称”参数的值。目的是使用这样的东西:

A a;

a["iii"] = 10;
int i = a["iii"];

a["ddd"] = 3.141519;
double d = a["ddd"];

a["sss"] = "string";
string s = a["sss"];

据我所知,这是一个大问题:编译器如何推导模板参数 VAL_TYPE在 A::operator[] 中。

这样的想法有可能实现吗?我阅读了很多帖子,但仍然找不到任何解决方案。

在Qt库的框架下可以吗?

最佳答案

最接近的是:

#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 变体是一种“总和”类型,它只包含一个对象,该对象具有它模板化的事物之一的类型。所以换句话说,这里它们包含字符串、整数或 double 。

当一个 boost 变体被分配时,它会根据分配的类型进行类型推断并做正确的事情。但是它无法轻松地提供对所有类型的隐式转换。所以你必须明确地提取值(value)。坦率地说,我会建议按原样使用它并接受它,但我敢肯定你没有听说过它,所以......

在您的特定情况下,如果您愿意放弃通用性,则可以这样做。基本上,您只需编写一个包含 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 提供了到 a 的隐式转换字符串并使用它。

问题是,就语言复杂性而言,这是打开了一个非常大的蠕虫 jar 头,不值得。它实际上是否应该通过引用提供按值转换,constness,rvalues 等等。还值得考虑的是,如果变体不包含,boost::get 将非常大声地(通过抛出)失败请求的类型,所以你现在有一个看起来无辜的赋值操作很容易抛出的情况。我建议学习 boost 变体(它可能很快就会成为标准的一部分,它已经被广泛讨论)并学习那里使用的一些技术,比如访问者。它们起初可能很陌生,但它们工作得很好,它们发挥了 C++ 的优势,而不是试图让 C++ 表现得像 python。

关于c++ - 返回模板类中的模板参数推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37993972/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com