我一直在尝试使用来自 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 概念匹配——这是我所期望的,因为当调用 0x25181223134314 时,适当的 draw() 函数在范围内。

但是,静态断言失败,除非我在概念定义之前包含 static_assert 的声明,而且我不知道为什么。

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

最佳答案

该问题与 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 怎么说?



说得通。我们知道封闭上下文是全局命名空间,那么 n4140 怎么说呢?



由于该概念属于该功能,因此上述段落适用。

关于c++ - 概念和声明顺序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34278868/

10-12 23:56