有没有一种方法可以在基于枚举的可变参数模板函数之间进行选择,这比将函数包装在结构中更简单
Is there a way of selecting between variadic template functions based on an enum that is simpler than wrapping the functions in a struct?
当前代码如下:
// header file...
enum class FuncType {
AddTwoInts,
SquareAnInt
};
template<FuncType F, typename... Ts>
int getValue(Ts...);
// ----------------------------------------
// cpp file...
template<FuncType F>
struct FuncHelper;
template<>
struct FuncHelper<FuncType::AddTwoInts> {
static int func(int v1, int v2) {return v1 + v2;}
}
template<>
struct FuncHelper<FuncType::SquareAnInt> {
static int func(int v) { return v*v; }
}
template <FuncType F, typename... Ts>
int getValue(Ts... args) {
return FuncHelper<F>::func(args...);
}
// explicitly instantiate versions of getValue for each FuncType
// with the correct args...
template int getValue<FuncType::AddTwoInts, int, int>(int , int);
template int getValue<FuncType::SquareAnInt, int>(int)
以上可以通过包含标头然后调用 like 来使用
auto val = getValue<FuncType::AddTwoInts>( 3, 4 );
这是我想要的确切接口,但希望在不需要使用 FuncHelper 或等效的东西的情况下进行实现。有没有办法在编译时更直接地选择可变参数模板?
还有我没有看到的上述问题吗?我上面的实际用例是作为结构类型的工厂功能,该结构类型是一些数据 + 一个 std::函数。
如果你
只是想避免结构,你可以用SFINAE做到这一点。
#include <type_traits>
enum class FuncType {
AddTwoInts,
MulTwoInts,
SquareAnInt,
ReturnAnInt
};
template<FuncType F, typename... Ts>
int getValue(Ts...);
// ----------------------------------------
// cpp file...
template<FuncType F, typename std::enable_if<F == FuncType::AddTwoInts, int>::type D>
int getValue_aux(int v1, int v2) { return v1 + v2; }
template<FuncType F, typename std::enable_if<F == FuncType::MulTwoInts, int>::type D>
int getValue_aux(int v1, int v2) { return v1 * v2; }
template<FuncType F, typename std::enable_if<F == FuncType::SquareAnInt, int>::type D>
int getValue_aux(int v) { return v * v; }
template<FuncType F, typename std::enable_if<F == FuncType::ReturnAnInt, int>::type D>
int getValue_aux(int v) { return v; }
template<FuncType F, typename... Ts>
int getValue(Ts... args)
{
return getValue_aux<F, 0>(args...);
}
如果没有辅助函数,就不可能在内部有多个实现,仅仅是因为它们具有不同的arity(所以你需要一个地方来解压缩你的可变参数(。如果所有 impls 都具有相同的参数列表(或者可能的参数列表数量相对较少(,则可以简单地switch
FuncType
,让优化器在编译时选择正确的参数。
在 C++17 中,您可以执行以下操作:
template<FuncType F, typename... Ts>
int getValue(Ts...args)
{
if constexpr (F == FuncType::AddTwoInts) {
static_assert(sizeof...(Ts) == 2, "!");
return (args + ...);
} else {
static_assert(sizeof...(Ts) == 1, "!");
const auto& first = std::get<0>(std::tie(args...));
return first * first;
}
}
演示
相关文章:
- 选择要调用的构造函数
- 无法获取菜单选择以运行函数.C++
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- LLVM 选择找不到函数传递
- C++ 带有默认参数的结构,可选择在构造函数中更改
- 如何在"push_*()"和"emplace_*()"函数之间进行选择?
- 如何在字符函数中选择某些字符?
- OpenCL 内置函数选择
- 编译时构造函数选择
- 内联函数选择条件
- c - 函数选择显示读取后stdin中有数据
- Clang 和 GCC 在使用大括号表示法和initializer_list时在构造函数选择上存在分歧
- 最小化函数选择和函数调用开销
- 当参数是引用时,可变模板构造函数选择失败
- 在运行时为调用函数选择对象,不包含基类和模板
- 为什么const临时函数选择调用非const成员函数而不是const成员函数?
- 如何消除构造函数选择的强制转换
- 是否有可能编写一个抽象类,其中构造函数选择适当的子类在c++中实例化
- c++模板函数选择
- vector insert中重载模板函数选择(模式匹配)是如何工作的