我想做的是在从共享库中调用某些函数之前,将每个“ VariantType”(不同类型的联合)参数转换为其类型。我到目前为止正在做的事情在下面。它只有3种不同的类型和2个参数,并且需要很多行。但是我想用7种不同类型的变元参数来实现这一点。这与可变参数模板有关(另一个相关的问题:Template tuple - calling a function on each element)。或者,如果您知道更好的方法,请告诉我。
template<typename... T>
int call(const char* func_name, T... args) {
// this will call func_name(args...) somehow from a dll binary.
// If you need the implementation : https://hastebin.com/ocoyaniruj.cpp
}
int main(int argc, char** argv) {
const char* func_name = "func_name";
VariantType arg1 = "hello world!";
VariantType arg2 = 3.14;
if (arg1.get_type() == VariantType::INT) {
if (arg2.get_type() == VariantType::INT) {
call(func_name, (int)arg1, (int)arg2);
} else if (arg2.get_type() == VariantType::FLOAT){
call(func_name, (int)arg1, (float)arg2);
} else if (arg1.get_type() == VariantType::STRING){
call(func_name, (int)arg1, arg2.c_str());
}
} else if (arg1.get_type() == VariantType::FLOAT){
if (arg2.get_type() == VariantType::INT) {
call(func_name, (float)arg1, (int)arg2);
} else if (arg2.get_type() == VariantType::FLOAT){
call(func_name, (float)arg1, (float)arg2);
} else if (arg1.get_type() == VariantType::STRING){
call(func_name, (float)arg1, arg2.c_str());
}
} else if (arg1.get_type() == VariantType::STRING){
if (arg2.get_type() == VariantType::INT) {
call(func_name, arg1.c_str(), (int)arg2);
} else if (arg2.get_type() == VariantType::FLOAT){
call(func_name, arg1.c_str(), (float)arg2);
} else if (arg1.get_type() == VariantType::STRING){
call(func_name, arg1.c_str(), arg2.c_str());
}
}
return 0;
}
您有一个凌乱且非常局部的运行时反射机制。我敢肯定,您在使用这些东西时会感到非常痛苦……所以首先要考虑的是:
说了-您可以使用C ++自己的变体类型:std::variant
,std::visit
和模板化的访问者,如this question。
这是下面的样子:
#include <variant>
#include <iostream>
#include <string>
int main() {
using variant_type = std::variant<int, float, std::string>;
variant_type v1{"hello world!"};
variant_type v2{3.14f};
std::visit([](auto&& x, auto&& y) {
// I used this as a stub:
//
// std::cout << x << " , " << y << '\n';
//
// but you want:
call(func_name, x, y);
}, v1, v2);
}
尽管有一个警告-这不会从您的字符串中提取c_str()
。如果您也想这样做,则可以执行以下两项操作之一:
const char*
。x
和y
,您可以具有模板化的转换器函数,该函数通常不执行任何操作,但是将.c_str()
用于常量字符串引用。但是我不太喜欢第二种方法。