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

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

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...