c++ - 用概念检查属性类型
问题描述
我想检查结构/类的属性是否符合我对概念的需求,但编译器抱怨。
例子:
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()
按预期工作。这里有什么问题?
参见编译器资源管理器
- clang:按预期工作
- gcc 10.1.1 失败并显示错误消息
- gcc 主干:冰!瑞银:-
更新(11 月 21 日 12 日)
- gcc 中继(版本 12.xx)有效
似乎有人已经修复了这个错误: 错误报告
解决方案
GCC 实际上是正确的(拒绝代码时,不会发疯)。引用标准
[expr.prim.req.compound]/ 1.3
- 如果存在返回类型要求,则:
- 执行将模板参数(如果有)替换为返回类型要求。
decltype((E))
应满足类型约束的立即声明的约束 ([temp.param]) 。
E
是我们的表达式,即n.value
。
现在,decltype(n.value)
is char
or int
,这是因为decltype
对类成员访问和 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;
}
推荐阅读
- dotnetrdf - 如何在 dotnetrdf QueryBuilder 中保持绑定顺序?
- ms-access - VS 2015 错误:指定的 DSN 包含驱动程序和应用程序之间的体系结构不匹配
- android-studio - 当我更改包名称时,我收到此错误“无效的包名称”
- architecture - MMO 等多人游戏如何处理大量请求
- python - Flask_SQLAlchemy create_all() 不起作用
- visual-studio-2019 - 如何解决 LNK2019 未解决的外部 __imp____iob_func
- r - 为什么我在 R 中将类别视为 0?
- python - 无法为我的 tkinter 应用程序设置背景颜色?
- java - XStream XStreamMarshaller CannotResolveClassException java.util.ArrayList
- typescript - 打字稿UTC到本地时间