我想检查结构/类的属性是否符合我的概念需求,但是编译器抱怨。
示例:
struct N
{
char value;
auto Get() { return value; }
};
struct M
{
int value;
auto Get() { return value; }
};
void func3( auto n )
requires requires
{
//{ n.Get() } -> std::same_as<int>;
{ n.value } -> std::same_as<int>;
}
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void func3( auto n )
requires requires
{
//{ n.Get() } -> std::same_as<char>;
{ n.value } -> std::same_as<char>;
}
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
int main()
{
M m;
N n;
func3( n );
func3( m );
}结果会产生更长的一串信息( gcc 10.1.1 )
main.cpp: In function 'int main()':
main.cpp:202:18: error: no matching function for call to 'func3(N&)'
202 | func3( n );
| ^
main.cpp:154:10: note: candidate: 'void func3(auto:15) requires requires{{func3::n.value} -> decltype(auto) [requires std::same_as<<placeholder>, int>];} [with auto:15 = N]'
154 | void func3( auto n )
| ^~~~~
main.cpp:154:10: note: constraints not satisfied
main.cpp: In instantiation of 'void func3(auto:15) requires requires{{func3::n.value} -> decltype(auto) [requires std::same_as<<placeholder>, int>];} [with auto:15 = N]':
main.cpp:202:18: required from here
main.cpp:154:10: required by the constraints of 'template<class auto:15> void func3(auto:15) requires requires{{func3::n.value} -> decltype(auto) [requires std::same_as<<placeholder>, int>];}'
main.cpp:155:18: in requirements [with auto:15 = N]
main.cpp:158:13: note: 'n.value' does not satisfy return-type-requirement
158 | { n.value } -> std::same_as<int>;
| ~~^~~~~
cc1plus: note: set '-fconcepts-diagnostics-depth=' to at least 2 for more detail
main.cpp:165:10: note: candidate: 'void func3(auto:16) requires requires{{func3::n.value} -> decltype(auto) [requires std::same_as<<placeholder>, char>];} [with auto:16 = N]'
165 | void func3( auto n )
| ^~~~~
main.cpp:165:10: note: constraints not satisfied
main.cpp: In instantiation of 'void func3(auto:16) requires requires{{func3::n.value} -> decltype(auto) [requires std::same_as<<placeholder>, char>];} [with auto:16 = N]':
main.cpp:202:18: required from here
main.cpp:165:10: required by the constraints of 'template<class auto:16> void func3(auto:16) requires requires{{func3::n.value} -> decltype(auto) [requires std::same_as<<placeholder>, char>];}'
main.cpp:166:18: in requirements [with auto:16 = N]
main.cpp:169:13: note: 'n.value' does not satisfy return-type-requirement
169 | { n.value } -> std::same_as<char>;
| ~~^~~~~
main.cpp:203:18: error: no matching function for call to 'func3(M&)'
203 | func3( m );
| ^
main.cpp:154:10: note: candidate: 'void func3(auto:15) requires requires{{func3::n.value} -> decltype(auto) [requires std::same_as<<placeholder>, int>];} [with auto:15 = M]'
154 | void func3( auto n )
| ^~~~~
main.cpp:154:10: note: constraints not satisfied
main.cpp: In instantiation of 'void func3(auto:15) requires requires{{func3::n.value} -> decltype(auto) [requires std::same_as<<placeholder>, int>];} [with auto:15 = M]':
main.cpp:203:18: required from here检查Get()函数返回类型的版本如预期的那样工作。这里怎么了?
最新情况( 12. 11月21日)
似乎有人修复了这个bug:错误报告
发布于 2020-07-08 10:07:52
GCC实际上是对的(当拒绝这条代码时,不要发疯)。引用标准
expr.prim.req.compound/1.3
decltype((E))类型约束的立即声明约束(decltype((E))).E是我们的表达方式,即n.value。
现在,decltype(n.value)是char或int,这是因为对类成员访问和id表达式具有特殊规则。。但decltype((n.value))是char&或int&。在处理通用表达式时,值类别是用decltype类型编码的(例如带括号的类成员访问)。
当我们修改你的例子时,你的例子在GCC中起了作用。
void func3( auto n )
requires requires
{
//{ n.Get() } -> std::same_as<int>;
{ n.value } -> std::same_as<int&>;
}
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
void func3( auto n )
requires requires
{
//{ n.Get() } -> std::same_as<char>;
{ n.value } -> std::same_as<char&>;
}
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}发布于 2020-07-08 10:10:07
根据[expr.prim.req.compound]/1.3
如果存在返回类型要求,则:
decltype((E))类型约束的立即声明约束(decltype((E))).示例:给定概念C和D,
需要{ E1 } -> C;{ E2 } -> D;};
等于
需要{ E1;需要C;E2;需要D;};
(包括n为零的情况)。-最后一个例子而且,从[dcl.type.decltype]/1,特别是[dcl.type.decltype]/1.5应用
对于表达式
E,由decltype(E)表示的类型定义如下:
E decltype(E) 是lvalue,则 decltype(E)是 T&,,其中T是E的类型;因此,由于value是{ n.value } -> std::same_as<int>;表达式中的一个lvalue,因此需要为返回类型int&匹配{ n.value }表达式的返回类型需求-> std::same_as<...>;上的类型约束。
#include <iostream>
#include <type_traits>
template <typename T> struct Foo {
T value;
auto getValue() { return value; }
};
using FooInt = Foo<int>;
using FooChar = Foo<char>;
void abbreviatedFunctionTemplate(auto n) requires requires {
{ n.value } -> std::same_as<int&>; }
{ std::cout << "int overload\n" << std::endl; }
void abbreviatedFunctionTemplate(auto n) requires requires {
{ n.getValue() } ->std::same_as<char>; }
{ std::cout << "char overload\n" << std::endl; }
int main() {
abbreviatedFunctionTemplate(FooInt{}); // int overload
abbreviatedFunctionTemplate(FooChar{}); // char overload
}https://stackoverflow.com/questions/62791460
复制相似问题