gpt4 book ai didi

C++条件模板编译基于数据类型

转载 作者:搜寻专家 更新时间:2023-10-30 23:53:16 24 4
gpt4 key购买 nike

我真的希望我可以使用 C++ (11) 模板实现这一点,但我在这里遇到了一些问题。所以我们有一个自定义指针对象,它在内部可以是这些类型中的任何一种:它自己类型的对象列表/一个 int/a char/bool/long/double/char* 或任何其他原始类型,它由此对象存储的标志。有一些全局方法可以从此对象中获取特定类型的值。

现在,我的目的很简单。我知道对于我的情况,我的对象是此类对象的列表,所以我想编写一个这样的函数,因为这是一个常见的场景:

template <typename T>
std::vector<T> List_To_Vector(Object& list)
{
std::vector<T> vec;
int listSize = Func_Size(list);
for (int i = 0; i < listSize; ++i)
{
//let's say this function gives list items one by one
Object arg = Func_Next(list);
if (std::is_same<T, int>::value || std::is_same<T, unsigned int>::value)
vec.push_back((T)Func_IntValue(arg));
else if (std::is_same<T, float>::value || std::is_same<T, double>::value)
vec.push_back((T)Func_DoubleValue(arg));
else if (std::is_same<T, std::string>::value || std::is_same<T, char*>::value)
vec.push_back((T)Func_StringValue(arg)); //Func_StringValue returns char*, so conversion to std::string should work
else if (std::is_same<T, bool>::value)
vec.push_back(Func_BoolValue(arg));
else if (std::is_same<T, char>::value)
vec.push_back(Func_CharValue(arg));

vec.push_back(val);
}

return vec;
}

int main()
{
Object listContainingStrings = GetListOfNames();
Object listContainingNumbers = GetListOfNumbers();
std::vector<string> vec1 = List_To_STD_Vector<string>(listContainingStrings);
std::vector<int> vec2 = List_To_STD_Vector<int>(listContainingNumbers);
return 0;
}

问题是,C++ 在这里提示,因为它试图编译采用 T = std::string 的代码,而 int 到 string 或 float 到 string 的转换将失败。我在这里真正想要的是一种在类型被检测为 int 而不是任何其他类型时编译代码的 int 部分的方法。我可以使用模板函数特化或重载,但后来我认为它确实违背了模板的目的,我可以为 8 种不同的类型(例如 List_To_String_Vector、List_To_Int_Vector 等)编写 8 个不同的函数。

我还尝试了另一种 hack,在每个返回类型的地址上使用 reinterpret_cast ,然后取消引用它以将其添加到 vector 中。那种工作,但有编译器警告,我认为这是未定义的行为。

有没有办法让它正常工作?

谢谢!

最佳答案

The fundamental theorem of software engineering :

We can solve any problem by introducing an extra level of indirection.

List_To_Vector做得太多了——都是从 Object 转换过来的至 T , 并填写 vector ;抽象出前者,解决方案就变得自然了。一、List_To_Vector :

template<typename T>
std::vector<T> List_To_Vector(Object& list) {
std::vector<T> vec;
for (int i = 0, listSize = Func_Size(list); i < listSize; ++i) {
vec.push_back(Object_To<T>(Func_Next(list)));
}
return vec;
}

现在您可以重载或专门化 Object_To有必要的。这是使用 SFINAE 的一种方法:

// not strictly necessary, but reduces noise a bit
template<bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;

template<typename T>
auto Object_To(Object arg)
-> enable_if_t<std::is_same<T, int>{} || std::is_same<T, unsigned>{}, T>
{
return (T)Func_IntValue(arg);
}

template<typename T>
auto Object_To(Object arg)
-> enable_if_t<std::is_same<T, float>{} || std::is_same<T, double>{}, T>
{
return (T)Func_DoubleValue(arg);
}

template<typename T>
auto Object_To(Object arg)
-> enable_if_t<std::is_same<T, std::string>{} || std::is_same<T, char*>{}, T>
{
return (T)Func_StringValue(arg);
}

template<typename T>
auto Object_To(Object arg) -> enable_if_t<std::is_same<T, bool>{}, T>
{
return Func_BoolValue(arg);
}

template<typename T>
auto Object_To(Object arg) -> enable_if_t<std::is_same<T, char>{}, T>
{
return Func_CharValue(arg);
}

使用类似于 boost::fusion::map<> 的东西如果您负担得起依赖性,可以使它变得更干净。

关于C++条件模板编译基于数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41806062/

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