首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用概念检查属性类型

用概念检查属性类型
EN

Stack Overflow用户
提问于 2020-07-08 09:16:23
回答 2查看 423关注 0票数 3

我想检查结构/类的属性是否符合我的概念需求,但是编译器抱怨。

示例:

代码语言:javascript
复制
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 )

代码语言:javascript
复制
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后备箱:冰!瑞银:-

最新情况( 12. 11月21日)

  • gcc主干(12.x.x.版)作品

似乎有人修复了这个bug:错误报告

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-08 10:07:52

GCC实际上是对的(当拒绝这条代码时,不要发疯)。引用标准

expr.prim.req.compound/1.3

  • 如果返回类型需求存在,那么:
    • 将模板参数(如果有的话)替换为返回类型要求。
    • 应满足decltype((E))类型约束的立即声明约束(decltype((E))).

E是我们的表达方式,即n.value

现在,decltype(n.value)charint,这是因为对类成员访问和id表达式具有特殊规则。。但decltype((n.value))char&int&。在处理通用表达式时,值类别是用decltype类型编码的(例如带括号的类成员访问)。

当我们修改你的例子时,你的例子在GCC中起了作用。

代码语言:javascript
复制
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;
}
票数 5
EN

Stack Overflow用户

发布于 2020-07-08 10:10:07

根据[expr.prim.req.compound]/1.3

如果存在返回类型要求,则:

  • 将模板参数(如果有的话)替换为返回类型要求。
  • 应满足decltype((E))类型约束的立即声明约束(decltype((E))).示例:给定概念CD, 需要{ E1 } -> C;{ E2 } -> D;}; 等于 需要{ E1;需要C;E2;需要D;}; (包括n为零的情况)。-最后一个例子

而且,从[dcl.type.decltype]/1,特别是[dcl.type.decltype]/1.5应用

对于表达式E,由decltype(E)表示的类型定义如下:

  • ..。
  • (1.5)否则,如果E decltype(E) 是lvalue,则 decltype(E) T&,,其中TE的类型;

因此,由于value{ n.value } -> std::same_as<int>;表达式中的一个lvalue,因此需要为返回类型int&匹配{ n.value }表达式的返回类型需求-> std::same_as<...>;上的类型约束。

代码语言:javascript
复制
#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
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62791460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档