繁体   English   中英

模板与lambda作为每个实例化的唯一默认参数

[英]template with lambda as unique default parameter on each instantiation

我正在寻找一种方法来自动使默认模板参数在每次实例化模板时都是唯一的。 由于lambda表达式创建的未命名函数对象具有不同的类型,我想以某种方式采用它们。 随着标准愚蠢删除的最近更改“一个lambda表达式不会出现在......模板参数中”限制(参见未评估上下文中的lambdas的措辞 ),这似乎是一个好主意。 所以我编写了以下有点编写最近gcc和clang的工作片段:

#include <type_traits>

template<void ( * ) (void) = [](){}> class
unique final {};

static_assert(false == ::std::is_same_v<unique<>, unique<>>);

int main()
{
    return 0;
}

这是一种可行的方法还是其中一种“形成不良,无需诊断”的案例?

一些额外的上下文:我想使用它来实现Ada样式的强类型定义,这些定义应该在单个翻译单元中工作,而无需手动发明未使用的唯一标记:

struct _tag_WowInt {};
using Int = type<int, _tag_WowInt>;
struct _tag_SoUnique {};
using DifferentInt = type<int, _tag_SoUnique>;

Upd1:我想提一下,涉及__COUNTER__或类似宏的方法在一般情况下不起作用,因为它们只会被预处理器扩展一次, 例如在模板内部使用时不会产生唯一类型

我相信你是对的,在我看来,这是“形成不良,无需诊断”。 我认为[temp.res / 8.4][temp.res / 8.5]涵盖了这个问题:

(8.4) - 由于不依赖于模板参数的构造,或者由于不依赖于模板参数的构造,在其定义之后立即对模板进行假设实例化,或者

(8.5) - 在假设实例化中对这种构造的解释不同于在模板的任何实际实例化中对相应构造的解释 [ 注意 :在包括以下情况的情况下会发生这种情况:

(8.5.1) - 非依赖名称中使用的类型在定义模板但在执行实例化时完成时不完整,或者

(8.5.2) - 在模板定义中查找名称时发现了一个using声明,但实例化中相应作用域中的查找没有找到任何声明,因为using-declaration是一个包扩展而相应的包是空的, 要么

(8.5.3) - 实例化使用默认参数或默认模板参数,该参数尚未在定义模板的位置定义,或者

(8.5.4) - 模板实例化中使用的常量表达式评估

(8.5.4.1) - 整数或无范围枚举类型的const对象的值或

(8.5.4.2) - constexpr对象的值或

(8.5.4.3) - 参考或的值

(8.5.4.4) - constexpr函数的定义,并且在定义模板时未定义该实体,或

(8.5.5) - 由模板使用由非依赖的simple-template-id指定的类模板特化或变量模板特化,并且它是从模板未定义的部分特化实例化的。定义或命名一个在定义模板时未声明的显式特化。 - 结束说明 ]

即使您的用例未在说明的示例中明确列出,但在我的理解中,要求意味着unique<>必须在整个程序中引用相同的内容,否则它是错误的,不需要诊断。

这是CWG1850 委员会似乎不喜欢这种有状态的元编程。 constexpr计数器不再适用于较新版本的编译器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM