支持依赖于参数的查找的编译器

时间:2017-04-18 04:18:32

标签: c++ boost argument-dependent-lookup

在我们的代码库中,我们广泛使用boost::intrusive_ptr,在移动了一些标题后,我开始从clang中获得意外的编译错误:

In file included from C:/code/Signal.cpp:1:
In file included from C:/code/signal.h:3:
In file included from c:/boost_1_56_0/include/boost/smart_ptr.hpp:26:
In file included from c:/boost_1_56_0/include/boost/intrusive_ptr.hpp:16:
c:/boost_1_56_0/include/boost/smart_ptr/intrusive_ptr.hpp:68:34: error: call to function 'intrusive_ptr_add_ref' that is neither visible in the template definition nor found by argument-dependent lookup
        if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );

similar issues reported elsewhere。 我们前一段时间编写了使用boost::intrusive_ptr的代码,并在intrusive_ptr_add_ref命名空间中定义了所有这些独立函数(如boost)。在检查了我开始得到的编译错误的原因后,似乎我应该在我的命名空间中定义这些函数。来自description of intrusive_ptr

  

在支持argument-dependent lookup的编译器上,   应在intrusive_ptr_add_refintrusive_ptr_release中定义   与其参数对应的命名空间;否则,   定义需要进入名称空间提升。

我认为大多数现代编译器都支持ADL,但是,我无法找到关于编译器支持什么以及什么不支持ADL的确切信息。

所以,问题在于:这些编译器不支持ADL。我主要对微软编译器(VS2012,VS2015)以及最新版本的gcc和clang感兴趣。

1 个答案:

答案 0 :(得分:0)

根据this page,在Visual Studio 2008中添加了ADL支持。

有一些困难,我能够构建EGCS 1.1,这是1997年发布的第一个声称支持命名空间的GCC版本。我通过编译并运行以下程序来测试它:

#include <stdio.h>
namespace foo {
    class bar {};
    void baz(bar&) {
        puts("foo::baz");
    }
}

void baz(const foo::bar&) {
    puts("::baz");
}

int main() {
    foo::bar bar;
    baz(bar);
}

打印foo::baz,这是正确的。因此,即使在那些日子里,GCC也存在基本的ADL功能。我怀疑你甚至可以使用旧的编译器来构建Boost。

Clang 2.7也是对的。请注意,2010年发布的LLVM 2.7是默认情况下在Clang中启用C ++支持的第一个LLVM版本。有一些旧版本的Clang C ++前端,但我不认为它们被广泛使用,而且我太懒了,不能尝试从SVN构建它们。