Max*_*hof 15 c++ templates template-specialization
在某些情况下,如果尝试实例化某些模板,则使用always_false助手来导致无条件static_assert失败:
template <class... T> struct always_false : std::false_type {};
template<class T>
struct UsingThisShouldBeAnError {
static_assert(always_false<T>::value, "You should not use this!");
};
Run Code Online (Sandbox Code Playgroud)
该帮助程序是必需的,因为模板定义必须(至少在理论上)具有至少一组模板参数,可以为其生成有效的专业化名称,以便程序格式正确:
[temp.res] / 8:如果满足以下条件,则该程序格式错误,无需进行诊断:
- 无法为模板生成有效的专业化,并且模板没有实例化,或者
[...]
(static_assert(false, "You should not use this!");因此,上面的书写格式不正确,即使没有实例化模板,编译器也总是可以触发静态断言,这不是故意的。)
这是涉及此模式的问题的快速样本(包括进一步的解释):
always_false作为标准库中的工具可能会很有用,因此我们不必不断地编写它。但是,以下问题的答案使我怀疑这是否可能:
在那里(std::enable_if_t<T>总是关于[temp.res] / 8)产生一个论点,该论点始终是void或不是一种类型,任何人对其进行进一步专门化都是非法的。因此,依赖于理论上的“ std::enable_if特殊性”的模板可避免[temp.res] / 8子句,实际上会使程序格式错误,不需要诊断。
回到我的问题:如果提供了该标准always_false,它将不得不禁止图书馆用户照常对其进行专业化(出于明显的原因)。但是,根据上述推理,这将使always_false(在理论上可以专门用于除以外的东西std::false_type)整个观点破灭-关于[temp.res] / 8,它将与std::false_type直接使用相同。
我在这个推理上错了吗?还是标准库实际上不可能以always_false有意义/有用的方式提供(无需更改核心语言)?
在带有lambda的C ++ 20中,您可以执行以下操作:
template <class... T> struct always_false : std::false_type {};
// To have true, but for a type that user code can't reuse as lambda types are unique.
template <> struct always_false<decltype([](){})> : std::true_type{};
Run Code Online (Sandbox Code Playgroud)
释义Jarod的想法,可能是
template <class... T> struct always_false : std::false_type {};
template <> struct always_false</* implementation defined */> : std::true_type{};
Run Code Online (Sandbox Code Playgroud)
哪里/* implementation defined */可以填补std::_ReservedIdentifer。用户代码无法访问它,因为标识符是保留给库的,但是存在一个专门的名称true。那应该避免对专业化中的ODR和lambda产生疑问。
| 归档时间: |
|
| 查看次数: |
227 次 |
| 最近记录: |