使用概念是否允许在成员函数上使用 decltype

问题描述 投票:0回答:3

我开始知道对于一个成员函数名为

X
的类
func
,c++标准不允许我们写
decltype(X::func)
。因此,我预计下面给出的程序会产生类似
invalid use of non-static member function
的错误。但令我惊讶的是,程序编译所有3个编译器。

#include <iostream>
#include <type_traits> 
#include <concepts>

template < typename T >
concept test = std::same_as <decltype(T::func), int(int) >;

struct D
{
    int func(int);
};

int main()
{ 
    std::cout << test<D>;      
}    

以上程序由所有3个编译器编译。通过查看 [expr.prim.id],程序似乎格式不正确并且应该发出诊断。但是没有一个编译器提供任何错误。那么,以程序中显示的方式使用

concept
是否使程序格式正确,或者它仍然格式错误并且所有编译器都错了?

c++ language-lawyer c++20 c++-concepts decltype
3个回答
4
投票

以程序中显示的方式使用概念是否使程序合式

由于[temp.constr.normal],程序格式错误,无需诊断

表达式 E 的范式是约束 (13.5.2),定义如下:

  • 概念标识 C 的范式 是约束表达式的范式 C的,将参数中的A1,A2,...,An替换为C各自的模板参数后 每个原子约束中的映射。 如果任何此类替换导致无效类型或表达式, 程序格式错误;无需诊断。

(强调我的)

并且由于概念定义右侧的

constraint-expression
无效,因此从上面引用的参考文献可以得出我们有 IFNDR。


所有的编译器都错了吗?

不需要编译器来发出诊断信息。


0
投票

在约束满足检查期间的替换失败不会导致程序格式错误;它只会导致不满足约束。此处标准的相关文本是 [temp.constr.atomic]/3:

为了确定原子约束是否满足,首先将参数映射和模板参数代入其表达式。如果替换导致无效类型或表达式,则不满足约束。否则……

根据 [temp.names]/9,要确定

test<D>
的值,我们首先需要将
test
的约束表达式简化为其 normal 形式。为了方便起见,我们假设
same_as<T, U>
被定义为
std::is_same_v<T, U>
(实际上它略有不同,但这并不影响这个答案)。

标准化

test
的约束表达式导致具有映射 [
std::is_same_v<T, U>
->
T
,
decltype(T::func)
->
U
] 的原子约束
int(int)
。请注意,参数映射表示完全有效的类型(一个依赖),因此 [temp.constr.normal]/1.4(IFNDR 案例)不适用。

仅当

D
替换为 (
test
's)
T
时才形成无效表达式,根据上面引用的文本,这仅意味着
test<D>
false
,并且程序是合式的.


-2
投票

根据 C++ 标准,您提供的程序不应编译无误。尽管您使用的编译器可能存在允许这种用法的错误或非标准扩展,但不建议依赖此类行为,因为它可能导致代码不可移植并且可能无法按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.