lambda作为每个实例上唯一的默认参数的模板 [英] template with lambda as unique default parameter on each instantiation

查看:86
本文介绍了lambda作为每个实例上唯一的默认参数的模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法,该方法可在每次实例化模板时自动使默认模板参数唯一.由于由lambda表达式创建的未命名函数对象具有不同的类型,因此我想到以某种方式采用它们.随着标准daft的最新更改,删除了"lambda表达式不应出现在...模板参数中" 限制(请参见在最近的gcc和clang上编译:

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. 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. So I wrote the following kinda working snippet that compiles on recent gcc and 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?

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

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:

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

Upd1:我想提一下,涉及__COUNTER__或类似宏的方法在一般情况下将不起作用,因为它们只能被预处理器一次扩展,并且

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.

推荐答案

我相信您是对的,在我看来,这是格式错误,无需诊断".我认为这涵盖了 [temp.res/8.4]

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]:

(8.4)―紧随模板定义之后的假想实例化将由于以下原因而形成错误: 不依赖模板参数的构造,或者

(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.5)―在假设实例化中对此类构造的解释与解释不同 模板的任何实际实例中对应构造的作用. [注意:在以下情况下可能会发生这种情况:

(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. [Note: This can happen in situations including the following:

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

(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.2)―在模板定义中对名称的查找找到了using-声明,但是在实例化中相应范围内的查找未找到任何声明,因为using-declaration是一个包扩展,并且包是空的,或者

(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.3)―实例化使用在定义模板时尚未定义的默认参数或默认模板参数,或者

(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.4)―模板实例化中的常量表达式求值使用

(8.5.4) ― constant expression evaluation within the template instantiation uses

(8.5.4.1)―整数或无作用域枚举类型的const对象的值或

(8.5.4.1) ― the value of a const object of integral or unscoped enumeration type or

(8.5.4.2)― constexpr对象或

(8.5.4.2) ― the value of a constexpr object or

(8.5.4.3)―引用或

(8.5.4.3) ― the value of a reference or

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

(8.5.4.4) ― the definition of a constexpr function, and that entity was not defined when the template was defined, or

(8.5.5)―模板使用由非依赖的simple-template-id指定的类模板专业化或变量模板专业化,或者从当在以下情况下未定义的部分专业化实例化定义了模板,或者它命名了在定义模板时未声明的显式专门化名称. — 尾注]

(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. — end note]

即使注释的示例中未明确列出您的用例,但据我所知,该要求意味着unique<>在整个程序中必须引用相同的内容,否则格式不正确,无需诊断

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.

这是 CWG1850 .委员会似乎不喜欢这个 有状态的元编程. constexpr计数器不再起作用 在较新版本的编译器中.

This was CWG1850. The Committee appear to dislike this kind of stateful meta-programming. The constexpr counter no longer works in newer versions of the compilers.

这篇关于lambda作为每个实例上唯一的默认参数的模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆