【发布时间】:2020-10-08 10:37:41
【问题描述】:
我将从我想象的如何使用我想创建的代码开始。它不必完全像这样,但它是我在标题中“简洁”的意思的一个很好的例子。在我的例子中,它是将一个类型映射到一个相关的枚举值。
struct bar : foo<bar, foo_type::bar> { /* ... */ };
// \_/ \___________/
// ^ Type ^ Value
理想情况下,这应该是自动注册foo的第一个模板参数,一个类型,第二个,一个值之间的双向映射,只需使用继承语法和适当的模板参数,以便我以后可以执行以下示例中的操作。
foo_type value = to_value<bar>; // Should be foo_type::bar
using type = to_type<foo_type::bar>; // Should be bar
我知道我可以为每个类型-值对手动编写两个模板特化来执行此操作,但我想知道如果不使用宏,它是否可以不那么乏味。
我已经尝试过的是......
- 专门化模板别名以编写更少的代码来生成专门化。在当前的 C++ 版本 (17/20) 中显然不可能。
- 专门化继承的模板成员类型。
struct foo_base
{
template<typename T>
struct to_value
{};
template<foo_type E>
struct to_type
{};
};
template<typename T, foo_type E>
struct foo : public foo_base
{
template<>
struct to_value<T>
{
static constexpr auto value = E;
};
template<>
struct to_type<E>
{
using type = T;
};
};
然后它的使用方式与我在开始时介绍的类似。
foo_type value = foo_base::to_value<bar>::value; // Should be foo_type::bar
using type = foo_base::to_type<foo_type::bar>::type; // Should be bar
但它在 MSVC 上失败并出现以下错误。
明确的专业化; 'foo_base::to_value' 已经被实例化了
'foo_base::to_value': 无法在当前范围内专门化模板
我觉得如果没有明确的手动专业化可能无法实现,但 C++17 允许许多令人惊讶的基于模板的 hack,所以在我放弃这个想法之前想与更有经验的人确认一下。
【问题讨论】:
-
foo_type是什么? -
就我而言,这是一个范围枚举。我在其中一个编辑中添加了这个细节。
-
to_value很简单:只需让它在bar内部查看(您可以在foo包装器中添加任意符号)。 -
也许朋友功能会有一些用处,它们允许creepy stuff。
-
除了
bar之外,还有更多的派生类型。
标签: c++ templates c++17 template-meta-programming c++20