枚举值的编译时列表
Compile-time list of enum values
在现代C++(GCC 5.1.0,所以C++14,我猜(,在编译时传递enum
值列表的最快方法是什么,然后在运行时检查其中有哪些值?
enum foobar { foo, bar, baz };
template<????>
void f() {
if( contains<????, foo>() )
std::cout << "foo!";
if( contains<????, bar>() )
std::cout << "bar!";
if( contains<????, baz>() )
std::cout << "baz!";
}
f<foo,bar>();
注意:这是用于单元测试,因此速度等主要是无关紧要的,主要目的是让不熟悉代码的人可以破译它。
这是一个建议
#include <initializer_list>// pulled in by a lot of stuff
enum class options { foo,bar,baz };
void test_func(options opt)
{
}
int main()
{
auto test_vector = { options::foo, options::bar };
for (auto option : test_vector)
{
test_func(option);
}
return 0;
}
检查提供的测试向量是否包含它们应该包含的内容稍微复杂一些:
#include <initializer_list>
#include <algorithm>
#include <stdexcept>
enum class options { foo, bar, baz, wuz };
void test_func(options)
{
}
template<typename AT, typename BT>
void assert_test_vectors(AT a, BT check_these_items)
{
for (auto item : check_these_items)
{
auto test = std::find(a.begin(), a.end(), item) != a.end();
if (!test)
{
return throw std::runtime_error("You suck");
}
}
}
template<typename T>
void run_tests(T tests)
{
const auto better_have_these = { options::foo, options::bar };
assert_test_vectors(tests, better_have_these);
for (auto test : tests)
{
test_func(test);
}
}
int main()
{
const auto test_vectors = { options::foo, options::wuz };
run_tests(test_vectors);
return 0;
}
我不知道你是否还感兴趣,但是...回答你原来的问题...如果您切换模板参数的顺序contain
...我的意思是
if( contains<foo, ????>() )
而不是
if( contains<????, foo>() )
从 C++14 开始,您的contains
(在以下示例中重命名为containsFB
(可以是一个简单的constexpr
函数
template <foobar F0, foobar ... Fs>
constexpr bool containsFB ()
{
using unused = bool[];
bool ret { false };
(void)unused { false, ret |= F0 == Fs ... };
return ret;
}
从 C++17 开始,您还可以使用模板折叠,constantFB
可以编写为继承自std::true_type
或std::false_type
的类型特征。
template <foobar F0, foobar ... Fs>
struct containsFB : public std::integral_constant<bool, ((F0 == Fs) || ...)>
{ };
以下是完整的工作 C++14 示例
#include <iostream>
#include <utility>
enum foobar { foo, bar, baz };
template <foobar F0, foobar ... Fs>
constexpr bool containsFB ()
{
using unused = bool[];
bool ret { false };
(void)unused { false, ret |= F0 == Fs ... };
return ret;
}
/* C++17 alternative
template <foobar F0, foobar ... Fs>
struct containsFB : public std::integral_constant<bool, ((F0 == Fs) || ...)>
{ };
*/
template <foobar ... Fs>
void f ()
{
if( containsFB<foo, Fs...>() ) std::cout << "foo!";
if( containsFB<bar, Fs...>() ) std::cout << "bar!";
if( containsFB<baz, Fs...>() ) std::cout << "baz!";
}
int main ()
{
f<foo,bar>();
}
如果你想使containsFB
(函数或结构(更通用一点,你可以模板化值的类型;所以
template <typename T, T F0, T ... Fs>
而不是
template <foobar F0, foobar ... Fs>
可变参数选项。它打印"foo!bar!baz!foo!",正如预期的那样。
enum class foobar { foo, bar, baz };
void test() {}
template< typename F, typename... Fs >
void test( F Foo, Fs const&... args )
{
switch( Foo )
{
case foobar::foo:
std::cout << "foo!";
break;
case foobar::bar:
std::cout << "bar!";
break;
case foobar::baz:
std::cout << "baz!";
break;
}
test( args... );
}
int main() {
test( foobar::foo, foobar::bar, foobar::baz, foobar::foo );
}
相关文章:
- 使用简单类型列表实现的指数编译时间.为什么
- 使用 C++11 时列表中出现编译错误
- 编译包含指向模板函数的指针的初始值设定项列表时,gcc 出错,但 clang 不出错
- 有关具有编译错误的操纵列表的问题
- 枚举值的编译时列表
- 在编译时使用 gnu++11 过滤值列表,不使用 stdlib(Arduino 环境)
- Linux MinGW:在编译时,他输出了 8 个"nultiple definitions"列表
- 模板,从编译时初始化器列表中的数组分支为长度分支
- 为什么 GCC 6.3 在没有显式 C++11 支持的情况下编译此大括号初始化列表代码
- 在Visual Studio 2013中编译的STL列表代码在Visual Studio 2019中给出了错误.想知道原
- 编译模板函数时形式参数列表不匹配
- 我无法编译使用类和列表的程序
- 在构造函数的成员初始值设定项列表中使用带有指示符的初始值设定项列表以初始化匿名联合类型时出现编译错误
- 双链接列表:编译类错误
- 增强HANA编译时列表转换
- 使用带有初始值设定项列表的 Stroustrup PPP 书中的向量时出现编译错误
- C++14 元编程:在编译/初始化时自动构建类型列表
- Visual Studio:编译每个平台和配置上的模块列表
- 在C++17中使用空列表初始化构造函数时发生编译错误
- 模板链接列表编译错误