【发布时间】:2016-03-20 15:10:35
【问题描述】:
我一直在 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 问题。 ADL 不会检查全局命名空间,因为所涉及的类型都不是它的成员。取消注释模板上方的声明使 unqualified-name-lookup 能够在模板定义上下文中找到它。
-
因此,如果他将那个 void draw 声明放在命名空间 std。它应该可以工作。
-
我在开头的句子中缺少 SVN 参考。这有什么意义吗?
-
@Columbo 这实际上是有道理的,使用常规函数定义我可能最终会弄明白,但概念问题让我很困惑。把它写成答案,如果你愿意,我会接受它
-
@Columbo 这与 ADL 无关,它与在定义点或实例化点查找名称有关。 “工作”
draw和“损坏”draw都在同一个命名空间中。
标签: c++ c++17 c++-concepts