c – 在每个实例化中将lambda作为唯一默认参数的模板
作者:互联网
我正在寻找一种方法来自动使默认模板参数在每次实例化模板时都是唯一的.由于lambda表达式创建的未命名函数对象具有不同的类型,我想以某种方式采用它们.随着标准愚蠢删除的最近更改“一个lambda表达式不会出现在……模板参数”限制(见Wording for lambdas in unevaluated contexts),这似乎是一个好主意.所以我写了以下有点工作片段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;
}
这是一种可行的方法还是其中一种“形成不良,无需诊断”的案例?
一些额外的上下文:我想使用它来实现Ada样式的强类型定义,这些定义应该在单个翻译单元中工作,而无需手动发明未使用的唯一标记:
struct _tag_WowInt {};
using Int = type<int, _tag_WowInt>;
struct _tag_SoUnique {};
using DifferentInt = type<int, _tag_SoUnique>;
Upd1:我想提一下,涉及__COUNTER__或类似宏的方法在一般情况下不起作用,因为它们只会被预处理器扩展一次而且只有won’t yield unique types when used inside of template for example.
解决方法:
我相信你是对的,在我看来,这是“形成不良,无需诊断”.我认为这包括在内
[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.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) ― 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) ― 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) ― 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) ― constant expression evaluation within the template instantiation uses
(8.5.4.1) ― the value of a const object of integral or unscoped enumeration type or
(8.5.4.2) ― the value of a constexpr object or
(8.5.4.3) ― the value of a reference or
(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) ― 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]
即使您的用例未在说明的示例中明确列出,但在我的理解中,该要求意味着唯一的<>在整个程序中必须引用相同的东西,否则它是不正确的,不需要诊断.
这是CWG1850.委员会似乎不喜欢这个
一种有状态的元编程. constexpr
counter不再有效
在较新版本的编译器中.
标签:c20,c,lambda,language-lawyer,templates 来源: https://codeday.me/bug/20191004/1852816.html