我一直在尝试使用来自 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/