简体   繁体   English

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

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

I'm looking for a way to automatically make default template parameter be unique each time a template is instantiated. 我正在寻找一种方法来自动使默认模板参数在每次实例化模板时都是唯一的。 Since unnamed function objects created by lambda expressions have different types I thought of adopting them somehow. 由于lambda表达式创建的未命名函数对象具有不同的类型,我想以某种方式采用它们。 With recent changes to standard daft removing "A lambda-expression shall not appear in ... a template-argument" restriction (see Wording for lambdas in unevaluated contexts ) it seemed like a good idea. 随着标准愚蠢删除的最近更改“一个lambda表达式不会出现在......模板参数中”限制(参见未评估上下文中的lambdas的措辞 ),这似乎是一个好主意。 So I wrote the following kinda working snippet that compiles on recent gcc and clang : 所以我编写了以下有点编写最近gcc和clang的工作片段:

#include <type_traits>

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

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

int main()
{
    return 0;
}

Is this a viable approach or one of those "ill-formed, no diagnostic is required" cases? 这是一种可行的方法还是其中一种“形成不良,无需诊断”的案例?

Some additional context: I want to use this to implement Ada-style strong type definitions that should work in a single translation unit without manually inventing unique tags that would be otherwise unused: 一些额外的上下文:我想使用它来实现Ada样式的强类型定义,这些定义应该在单个翻译单元中工作,而无需手动发明未使用的唯一标记:

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

Upd1: I would like to mention that approaches involving __COUNTER__ or similar macros won't work in general case because they will be expanded by preprocessor only once and won't yield unique types when used inside of template for example . Upd1:我想提一下,涉及__COUNTER__或类似宏的方法在一般情况下不起作用,因为它们只会被预处理器扩展一次, 例如在模板内部使用时不会产生唯一类型

I believe that you are right, it seems to me that is "ill-formed, no diagnostic required". 我相信你是对的,在我看来,这是“形成不良,无需诊断”。 I think this is covered by [temp.res/8.4] and [temp.res/8.5] : 我认为[temp.res / 8.4][temp.res / 8.5]涵盖了这个问题:

(8.4) ― a hypothetical instantiation of a template immediately following its definition would be ill-formed due to a construct that does not depend on a template parameter, or (8.4) - 由于不依赖于模板参数的构造,或者由于不依赖于模板参数的构造,在其定义之后立即对模板进行假设实例化,或者

(8.5) ― the interpretation of such a construct in the hypothetical instantiation is different from the interpretation of the corresponding construct in any actual instantiation of the template . (8.5) - 在假设实例化中对这种构造的解释不同于在模板的任何实际实例化中对相应构造的解释 [ Note : This can happen in situations including the following: [ 注意 :在包括以下情况的情况下会发生这种情况:

(8.5.1) ― a type used in a non-dependent name is incomplete at the point at which a template is defined but is complete at the point at which an instantiation is performed, or (8.5.1) - 非依赖名称中使用的类型在定义模板但在执行实例化时完成时不完整,或者

(8.5.2) ― lookup for a name in the template definition found a using-declaration, but the lookup in the corresponding scope in the instantiation does not find any declarations because the using-declaration was a pack expansion and the corresponding pack is empty, or (8.5.2) - 在模板定义中查找名称时发现了一个using声明,但实例化中相应作用域中的查找没有找到任何声明,因为using-declaration是一个包扩展而相应的包是空的, 要么

(8.5.3) ― an instantiation uses a default argument or default template argument that had not been defined at the point at which the template was defined, or (8.5.3) - 实例化使用默认参数或默认模板参数,该参数尚未在定义模板的位置定义,或者

(8.5.4) ― constant expression evaluation within the template instantiation uses (8.5.4) - 模板实例化中使用的常量表达式评估

(8.5.4.1) ― the value of a const object of integral or unscoped enumeration type or (8.5.4.1) - 整数或无范围枚举类型的const对象的值或

(8.5.4.2) ― the value of a constexpr object or (8.5.4.2) - constexpr对象的值或

(8.5.4.3) ― the value of a reference or (8.5.4.3) - 参考或的值

(8.5.4.4) ― the definition of a constexpr function, and that entity was not defined when the template was defined, or (8.5.4.4) - constexpr函数的定义,并且在定义模板时未定义该实体,或

(8.5.5) ― a class template specialization or variable template specialization that is specified by a non-dependent simple-template-id is used by the template, and either it is instantiated from a partial specialization that was not defined when the template was defined or it names an explicit specialization that was not declared when the template was defined. (8.5.5) - 由模板使用由非依赖的simple-template-id指定的类模板特化或变量模板特化,并且它是从模板未定义的部分特化实例化的。定义或命名一个在定义模板时未声明的显式特化。 end note ] - 结束说明 ]

Even though your use case is not explicitly listed in the examples of the note, in my understanding the requirement implies that unique<> must refer to the same thing throughout the whole program, otherwise it is ill-formed, no diagnostic required. 即使您的用例未在说明的示例中明确列出,但在我的理解中,要求意味着unique<>必须在整个程序中引用相同的内容,否则它是错误的,不需要诊断。

This was CWG1850 . 这是CWG1850 The Committee appear to dislike this kind of stateful meta-programming. 委员会似乎不喜欢这种有状态的元编程。 The constexpr counter no longer works in newer versions of the compilers. constexpr计数器不再适用于较新版本的编译器。

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

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