C++ 异构列表
C++ Heterogeneous list
几个星期以来,我一直在互联网上搜索有关 C++ 中的异构列表(vector
、array
、list
)的信息,但是,在所有站点和论坛中,答案都是相同:boost::any
,但我想要一种用纯 C++ 实现的方法。我开发了这个:
#include <iostream>
#include <typeinfo>
#include <vector>
using namespace std;
//Compiler version g++ 6.3.0
class any
{
public:
auto get() {}
};
template<typename T>
class anyTyped : public any
{
public:
T val;
anyTyped(T x)
{
val = x;
}
T get()
{
return val;
}
};
class queue
{
vector<any*> x;
int len = 0;
public:
queue()
{
x.resize(0);
}
template<typename T>
void insert(T val)
{
any* ins = new anyTyped<T>(val);
x.push_back(ins);
len++;
}
int size()
{
return len;
}
auto& at(int idx)
{
return x[idx]->get();
}
};
int main()
{
queue vec;
vec.insert(5); //int
vec.insert(4.3); //float
vec.insert("txt"); //string
for (int i = 0; i < vec.size(); i++)
{
cout << vec.at(i);
}
return 0;
}
但是我得到这个错误:
source_file.cpp: In member function 'auto& queue::at(int)':
source_file.cpp:55:23: error: forming reference to void
return x[idx]->get();
^
source_file.cpp: In function 'int main()':
source_file.cpp:70:9: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'void')
cout << vec.at(i);
~~~~~^~~~~~~~~~~~
我知道问题在于使用 auto
作为 return 类型,在 auto get()
中 any
class 或 auto& at(int idx)
在 queue
class 中,但我不知道如何修复。
为了存储,所有异质数据必须在 C++ 中归结为同质的东西。 std::any
也不例外。为了使事物同质化,最重要的是继承和类型擦除(any
是后者的一个实例)。
应用于您的示例,这可能意味着,例如,您必须将 get
的 return 类型指定为固定类型。在最好的情况下,这将是您使用的所有类型 T
中的 std::common_type
。
获得灵感:
anyTyped<double> anyDouble{1.0};
anyTyped<int> anyInt{2};
std::vector<std::function<double()> > anyStore; //the chosen homogenous type is 'double'
//get() should be const, otherwise add a 'mutable'
anyStore.push_back([anyDouble]() { return anyDouble.get(); });
anyStore.push_back([anyInt]() { return anyInt.get(); });
您现在可以拨打
auto x = anyStore[0](); //x is a double
x = anyStore[1]();
在这两种情况下您都会得到 double
,但您不会取回 int
。
所有处理异构的运行时都基于类似的原则构建,但可能更复杂——这基本上意味着涉及更多层,直到链以同质类型结束。
您的 any
class 存在一些固有缺陷,我建议您在将其添加到 queue 之前解决这些问题。
主要问题是 C++ 是一种静态类型语言,从 vec.at(i)
中提取值很可能需要某种类型信息:vec.at<int>(i)
。
您的 any
实施将更加健壮和智能,可以按照您预期的方式工作。使用 boost/any.hpp
或 std::any
。如果您不想包含整个 boost,请尝试仅包含任何 header 或查找 any
库的单个 header 实现。
在您的情况下,您的 queue 实现并没有什么特别之处,因为异质性将包含在 any
类型中。
如果您真的想自己实现,请查看 boost 的实现,看看是否可以从中派生。它不会像您对动态类型语言所期望的那样简单。
http://www.boost.org/doc/libs/1_55_0/boost/any.hpp
在一天结束时,您将需要指定要从 any
class.
中提取的数据类型
几个星期以来,我一直在互联网上搜索有关 C++ 中的异构列表(vector
、array
、list
)的信息,但是,在所有站点和论坛中,答案都是相同:boost::any
,但我想要一种用纯 C++ 实现的方法。我开发了这个:
#include <iostream>
#include <typeinfo>
#include <vector>
using namespace std;
//Compiler version g++ 6.3.0
class any
{
public:
auto get() {}
};
template<typename T>
class anyTyped : public any
{
public:
T val;
anyTyped(T x)
{
val = x;
}
T get()
{
return val;
}
};
class queue
{
vector<any*> x;
int len = 0;
public:
queue()
{
x.resize(0);
}
template<typename T>
void insert(T val)
{
any* ins = new anyTyped<T>(val);
x.push_back(ins);
len++;
}
int size()
{
return len;
}
auto& at(int idx)
{
return x[idx]->get();
}
};
int main()
{
queue vec;
vec.insert(5); //int
vec.insert(4.3); //float
vec.insert("txt"); //string
for (int i = 0; i < vec.size(); i++)
{
cout << vec.at(i);
}
return 0;
}
但是我得到这个错误:
source_file.cpp: In member function 'auto& queue::at(int)':
source_file.cpp:55:23: error: forming reference to void
return x[idx]->get();
^
source_file.cpp: In function 'int main()':
source_file.cpp:70:9: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'void')
cout << vec.at(i);
~~~~~^~~~~~~~~~~~
我知道问题在于使用 auto
作为 return 类型,在 auto get()
中 any
class 或 auto& at(int idx)
在 queue
class 中,但我不知道如何修复。
为了存储,所有异质数据必须在 C++ 中归结为同质的东西。 std::any
也不例外。为了使事物同质化,最重要的是继承和类型擦除(any
是后者的一个实例)。
应用于您的示例,这可能意味着,例如,您必须将 get
的 return 类型指定为固定类型。在最好的情况下,这将是您使用的所有类型 T
中的 std::common_type
。
获得灵感:
anyTyped<double> anyDouble{1.0};
anyTyped<int> anyInt{2};
std::vector<std::function<double()> > anyStore; //the chosen homogenous type is 'double'
//get() should be const, otherwise add a 'mutable'
anyStore.push_back([anyDouble]() { return anyDouble.get(); });
anyStore.push_back([anyInt]() { return anyInt.get(); });
您现在可以拨打
auto x = anyStore[0](); //x is a double
x = anyStore[1]();
在这两种情况下您都会得到 double
,但您不会取回 int
。
所有处理异构的运行时都基于类似的原则构建,但可能更复杂——这基本上意味着涉及更多层,直到链以同质类型结束。
您的 any
class 存在一些固有缺陷,我建议您在将其添加到 queue 之前解决这些问题。
主要问题是 C++ 是一种静态类型语言,从 vec.at(i)
中提取值很可能需要某种类型信息:vec.at<int>(i)
。
您的 any
实施将更加健壮和智能,可以按照您预期的方式工作。使用 boost/any.hpp
或 std::any
。如果您不想包含整个 boost,请尝试仅包含任何 header 或查找 any
库的单个 header 实现。
在您的情况下,您的 queue 实现并没有什么特别之处,因为异质性将包含在 any
类型中。
如果您真的想自己实现,请查看 boost 的实现,看看是否可以从中派生。它不会像您对动态类型语言所期望的那样简单。
http://www.boost.org/doc/libs/1_55_0/boost/any.hpp
在一天结束时,您将需要指定要从 any
class.