在枚举上构造类型并转发不同数量的参数
Construct type over enum and forward different number of arguments
假设我有几个类型绑定到一个变体中。另一方面,我有一个枚举,可以从中推断出一些以前的类型,所以我可以有一个运行时伪工厂:
#include <boost/variant.hpp>
enum class Type { W, X, Y, Z };
struct A {};
struct B
{
B(int) {}
};
struct C
{
C(int, int) {}
};
using variant_t = boost::variant<A, B, C>;
template<typename... Args>
variant_t MakeVariantOverEnum(Type type, Args&&... args)
{
switch (type)
{
case Type::X: return B(std::forward<Args>(args)...); break;
case Type::Z: return C(std::forward<Args>(args)...); break;
default: return A(std::forward<Args>(args)...); break;
}
}
// meant to be fully runtime
const Type GetTypeFromIO() { return Type::Z; }
const int GetFirstArgFromIO() { return 0; }
const int GetSecondArgFromIO() { return 0; }
int main()
{
const Type type = GetTypeFromIO();
const int firstArg = GetFirstArgFromIO();
const int secondArg = GetSecondArgFromIO();
variant_t newVariant;
if (firstArg != 0 && secondArg != 0) newVariant = MakeVariantOverEnum(type, firstArg, secondArg);
else if (firstArg != 0) newVariant = MakeVariantOverEnum(type, firstArg);
else newVariant = MakeVariantOverEnum(type);
}
在此代码中困扰我的两件事:
** 如何通过传递所有参数然后丢弃那些"无效"情况(在我的示例中 ==0)来只调用 1 次 MakeVariantOverEnum?我可以在MakeVariantOverEnum中使用一些SFINAE机制来做到这一点吗?
** 它无法编译,因为编译器尝试将所有构造函数与所有参数匹配:
main.cpp: In instantiation of 'variant_t MakeVariantOverEnum(Type, Args&& ...) [with Args = {const int&, const int&}; variant_t = boost::variant<A, B, C>]':
main.cpp:44:100: required from here
main.cpp:24:59: error: no matching function for call to 'B::B(const int&, const int&)'
case Type::X: return B(std::forward<Args>(args)...); break;
^
main.cpp:24:59: note: candidates are:
main.cpp:9:2: note: B::B(int)
B(int) {}
^
main.cpp:9:2: note: candidate expects 1 argument, 2 provided
main.cpp:7:8: note: constexpr B::B(const B&)
struct B
^
main.cpp:7:8: note: candidate expects 1 argument, 2 provided
main.cpp:7:8: note: constexpr B::B(B&&)
main.cpp:7:8: note: candidate expects 1 argument, 2 provided
以此类推,对于其他类型...
所以我的问题是:在这一点上我怎样才能让它工作?
谢谢!
PS:代码在这里直播=> http://coliru.stacked-crooked.com/a/4bc1e326be27b3dd
最简单的问题方法:
enum class Type { W, X, Y, Z };
struct A {};
struct B
{
B(int) {}
};
struct C
{
C(int, int) {}
};
using variant_t = boost::variant<A, B, C>;
variant_t MakeVariantOverEnum(Type type, int param1, int param2)
{
switch (type)
{
case Type::X: return B(param1);
case Type::Z: return C(param1, param2);
default: return A();
}
}
// meant to be fully runtime
const Type GetTypeFromIO() { return Type::Z; }
const int GetFirstArgFromIO() { return 0; }
const int GetSecondArgFromIO() { return 0; }
int main()
{
const Type type = GetTypeFromIO();
const int firstArg = GetFirstArgFromIO();
const int secondArg = GetSecondArgFromIO();
variant_t newVariant = MakeVariantOverEnum(type, firstArg, secondArg);
}
可变参数模板只会使事情变得更加复杂,不会以任何方式帮助您。
如果所有结构都使用相同的参数(至少:如果使用参数,则在任何地方都使用相同的类型),这将起作用。但是,如果不同的对象有不同的参数类型,则需要考虑在 main 函数本身中执行切换(然后获取正确的参数)是否更容易:
假设以下扩展:
struct D
{
D(float) {}
}
所以现在你突然有一个情况,你的const int firstArg
会是一个漂浮物......(但是,这对 B 和 C 不起作用)
或者,您可以指定第三个参数float param3
并且仅在创建类型时使用此参数。(但是参数1和参数2呢?
注意:仍然可以使用一些工厂模式,但那会复杂得多(每个对象都需要自己的工厂,它将获得正确的参数,然后创建正确的结构......
相关文章:
- 是否可以在不扣除的情况下将模板参数转发到 make_*?
- 可变参数模板参数转发使用逗号运算符
- 如何通过可变参数模板将多个构造函数参数转发到数组初始值设定项列表?
- 将可变参数函数参数转发到 std::function 对象
- 我如何实现变异模式以将可变数量的参数转发到C 11中的函数
- 无临时实例的参数转发
- 如何将构造函数参数转发到 boost::optional
- 如何使包装类将其构造函数参数转发到 std::vector 的构造函数?
- 如何将 CMake 参数转发到外部项目
- 使用std::forward而不是将参数转发到另一个函数
- 使用declard和参数转发构造函数隐式复制结构
- 将可变参数模板参数转发到多个类成员
- Template()的参数转发使构造函数参数变为常量
- 我怎样才能完美地将参数转发到 STL 集合
- 如何在 C++11 中使用可变参数模板正确创建显式参数转发函数
- 使用默认参数转发引用
- 将可变模板参数转发到类似printf的函数
- static_cast的参数转发
- Boost.Program_options:将"--"后面的参数转发到另一个程序
- 将参数转发给模板成员函数