微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 概念和申报单

我一直在试验SVN GCC中的概念.我遇到一个我怀疑是由于我缺乏理解的问题,如果有人能指出我正确的方向,我会感激的.我的代码是:
#include <iostream>
#include <string>

// Uncomment this declaration to change behavIoUr
//void draw(const std::string&);

template <typename T>
concept bool Drawable() {
    return requires (const T& t) {
        { draw(t) }
    };
}

void draw(const std::string& s)
{
    std::cout << s << "\n";
}

int main()
{
    static_assert(Drawable<std::string>()); // Fails
}

在这里我定义一个简单的概念,Drawable,它的目的是要求给定一个类型为const T&,draw(t)的编译参数.

然后我定义一个函数draw(const std :: string&),它将字符串“绘制”为cout.最后,我检查std :: string是否匹配Drawable概念 – 我本来会期望它,因为在调用static_assert时,适当的draw()函数在范围内.

但是,静态断言失败,除非我在概念定义之前包含一个draw(const std :: string&)声明,而且我不知道为什么.

这是预期的行为与概念,还是我做错了?

解决方法

这个问题与ADL毫无关系),只是通过名称查找. GCC使用的概念草案是n4377,但是我将使用的C标准草案是n4140.首先,在潜入标准之前,我们可以将您的问题变成我们知道应该运作的形式的MCVE.例:
template<typename T> concept bool C =
  requires (T a,T b) {
    a + b;
  };

这是一个简单的要求,[expr.prim.req.simple],它检查表达式的有效性.重写我们的示例以匹配表单:

template<typename T> concept bool Drawable = 
  requires (const T& x) { 
    draw(x); 
  };

我们可以看到我们的语法很好.好的,n4377怎么说?

[expr.prim.req]/1 A requires-expression provides a concise way to
express requirements on template arguments. A requirement is one that
can be checked by name lookup (3.4) or by checking properties of types
and expressions.

[expr.prim.req]/6 The requirement-body is comprised of a sequence of
requirements. These requirements may refer to local parameters,
template parameters,and any other declarations visible from the
enclosing context. …

说得通.我们知道包围的上下文是全局命名空间,所以n4140说什么?

[basic.lookup.unqual]/1 In all the cases listed in 3.4.1,the scopes
are searched for a declaration in the order listed in each of the
respective categories; name lookup ends as soon as a declaration is
found for the name. If no declaration is found,the program is
ill-formed.

A name used in the deFinition of a function following the function’s
declarator-id that is a member of namespace N (where,only for the purpose of exposition,N Could represent the global scope) shall be
declared before its use in the block in which it is used or in one of
its enclosing blocks (6.3) or,shall be declared before its use in
namespace N

由于这个概念适用于该功能,所以上面的段落适用.

原文地址:https://www.jb51.cc/c/115694.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐