有没有一种好的方法可以在C++中的可变模板中对函数参数强制执行类型限制
Is there a good way to enforce type restrictions on function parameters in a variadic template in C++?
我有一个枚举,我们称之为Type。它的值如下:
enum Type { STRING, TYPE_A_INT, TYPE_B_INT};
我想写一个函数Foo,它可以任意取许多类型为{int,string}的值,但要强制模板参数与参数类型匹配。
理想情况下,它将表现为:
Foo<STRING, TYPE_A_INT>("str", 32); // works
Foo<STRING, TYPE_B_INT>("str", 32); // works
Foo<STRING, TYPE_B_INT, TYPE_A_INT, STRING>("str", 32, 28, "str"); // works
Foo<STRING, TYPE_B_INT>("str", "str"); // doesn't compile
有办法做到这一点吗?
我似乎可以做下面这样的事情,但这不起作用,因为Args是Type,Args是{string,int}。
template<typename Arg, typename... Args>
std::enable_if<(std::is_same<Arg, STRING>::value)>
Foo(String arg, Args... args) {
// Do stuff to arg, then make recursive call.
Foo(args);
}
template<typename Arg, typename... Args>
std::enable_if<(std::is_same<Arg, TYPE_A_INT>::value)>
Foo(int arg, Args... args) {
// Do stuff to arg, then make recursive call.
Foo(args);
}
我可以用之类的东西来包装这些论点
pair<Type, string>
pair<Type, int>
但如果能避免这种情况,那就太好了。
一个简单的方法是创建一个从枚举器到所需类型的映射,并用它来构建函数参数列表-我想你可以把它看作是"枚举器特征":
#include <iostream>
#include <string>
enum Type {STRING, TYPE_A_INT, TYPE_B_INT};
template<Type> struct type_from;
template<> struct type_from<STRING> { using type = std::string; };
template<> struct type_from<TYPE_A_INT> { using type = int; };
template<> struct type_from<TYPE_B_INT> { using type = int; };
template<Type E> using type_from_t = typename type_from<E>::type;
template<Type... Es> void Foo(type_from_t<Es>... args)
{
// Do stuff with args.
using expander = int[];
(void)expander{0, (std::cout << args << ' ', 0)...};
std::cout << 'n';
}
int main()
{
Foo<STRING, TYPE_A_INT>("str", 32); // works
Foo<STRING, TYPE_B_INT>("str", 32); // works
Foo<STRING, TYPE_B_INT, TYPE_A_INT, STRING>("str", 32, 28, "str"); // works
// Foo<STRING, TYPE_B_INT>("str", "str"); // doesn't work
}
如果取消对最后一行的注释,您将得到一条很好的错误消息,告诉您到底是什么参数导致了问题。
当然,这并不能确保函数参数类型与枚举器特征所给出的类型完全相同,而是确保每个类型都有有效的隐式转换。据我所知,这正是您想要的,因为您的示例将字符串文本传递给std::string
s。
相关文章:
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 是否有任何建议来统一函数类型限定符并简化可恶的函数类型?
- 关于 C++ 中的函数类型定义
- 用于检测函数类型是否为否的特征
- 函数类型参数的模板参数推导
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- C++无效的函数类型转换
- STL 函数和函数类型与函数指针类型
- 如何将result_of与函数类型定义一起使用
- 将模板(没有规范)传递给 std::thread() 会出现错误:<未解析的重载函数类型>匹配错误
- C++ 编译错误:gnu_printf是无法识别的格式函数类型
- 专门用于"direct"函数类型(与函数指针类型相对)
- 将函数类型作为模板参数传递不会编译
- 通过参数传递 lambda(无函数类型模板)
- 如何在模板参数中分离函数类型返回类型和参数
- 为什么比较函数类型需要指定为模板参数?
- 带有限定符的函数类型定义用例
- 如何声明对函数类型的常量引用
- 非类型模板参数允许各种函数类型?