标签: argument-dependent-lookup

Koenig查找的基本原理

Koenig查找的基本原理是什么?

无法避免将其视为使您的代码更难以阅读且更不稳定的东西.

他们不能定义Koenig查找,以便它只适用于特定情况(即:非成员运营商)或明确要求时?

c++ rationale argument-dependent-lookup

6
推荐指数
1
解决办法
1039
查看次数

带有模板函数的嵌套命名空间中的C++ ADL

我对C++中的标准ADL分辨率有疑问.

以下是解释我的查询的示例代码:

#include <string>

// The mechanism:
namespace A {

 template< class C >
 ::std::string scope(const C*)
 { return "A"; }

 namespace B {

  template< class C >
  ::std::string scope(const C *foo)
  { return A::scope(foo)+"::B"; }

 } // namespace B
} // namespace A

::std::string scope(...)
{ return ""; }

// The test classes
struct foo {};
namespace A {
 struct foo {};
 namespace B {
  struct foo {};
 }
}

// The usage
int main()
{
  foo *Foo=0;
  A::foo …
Run Code Online (Sandbox Code Playgroud)

c++ standards argument-dependent-lookup

6
推荐指数
1
解决办法
686
查看次数

如何在ADL期间使功能模板成为最低优先级?

我有一个问题,我想提供一个函数的泛型版本,foo只有在调用绝对没有其他匹配时才可以应用.我如何修改下面的代码,这样last_resort::foo是更差的比赛derived::typebase::foo?我想找到一个解决方案,它不涉及修改定义, bar而是保留参数的类型last_resort::foo.

#include <iostream>

namespace last_resort
{

template<typename T> void foo(T)
{
  std::cout << "last_resort::foo" << std::endl;
}

}

template<typename T> void bar(T)
{
  using last_resort::foo;
  foo(T());
}

namespace unrelated
{

struct type {};

}

namespace base
{

struct type {};

void foo(type)
{
  std::cout << "base::foo" << std::endl;
}

}

namespace derived
{

struct type : base::type {};

}

int main()
{
  bar(unrelated::type()); // calls last_resort::foo
  bar(base::type());      // …
Run Code Online (Sandbox Code Playgroud)

c++ templates argument-dependent-lookup

6
推荐指数
1
解决办法
278
查看次数

为什么ADL优先于'std namespace'中的函数,但是等于用户定义的命名空间中的函数?

我有两个用于ADL的片段用于演示目的.这两个片段都是由VC10,gcc和comeau C++编译器编译的,结果对于这三个片段都是相同的.

<1> ADL反对使用用户定义的命名空间的指令:

#include <algorithm>
namespace N 
{ 
    struct T {}; 
    void swap(T,T) {} 
} 

namespace M 
{ 
    void swap(N::T,N::T) {} 
} 

int main() 
{ 
    using M::swap; 
    N::T o1,o2;
    swap(o1,o2); 
}
Run Code Online (Sandbox Code Playgroud)

编译结果:

error C2668: 'M::swap' : ambiguous call to overloaded function
could be 'void M::swap(N::T,N::T)'
or       'void N::swap(N::T,N::T)' [found using argument-dependent lookup]
Run Code Online (Sandbox Code Playgroud)

这是预期的,因为ADL不优先于正常查找结果加上ADL不是二等公民,ADL搜索结果与正常(非ADL)无法定义查找联合.这就是为什么我们有歧义.

<2> ADL反对使用std命名空间的指令:

#include <algorithm>
namespace N 
{ 
    struct T {}; 
    void swap(T,T) {}  //point 1
} 

namespace M 
{ 
    void swap(N::T,N::T) {} 
} 

int main() 
{ …
Run Code Online (Sandbox Code Playgroud)

c++ namespaces using-directives argument-dependent-lookup

6
推荐指数
2
解决办法
1169
查看次数

ADL 是否适用于全局命名空间?

诸如启用std类型输出之类的示例解释了如何使用ADL来“注入”某个函数/运算符,具体取决于 fn/op 应用到的类型。

我想知道 ADL 是否完全适用于全局命名空间,也就是说,using全局命名空间范围内声明(或通过 提供)的类型是否使 ADL在全局命名空间中寻找匹配的函数?

具体来说,这些是等价的。ADL?:

// 1 - at global namespace scope
struct GlobalType {};

template< class Ch, class Tr>
std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, GlobalType const& x)
{
    os << ...;
    return os;
} 

// 2 - within namespace
namespace ecaps {

    struct EcapsType {};

    template< class Ch, class Tr>
    std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, EcapsType const& x)
    {
        os << ...; …
Run Code Online (Sandbox Code Playgroud)

c++ namespaces using global-namespace argument-dependent-lookup

6
推荐指数
1
解决办法
743
查看次数

依赖于参数的查找和函数模板

这是一个例子:

#include <string>
#include <algorithm>
#include <memory>

using std::string;

int main()
{
    string str = "This is a string";

    // ok: needn't using declaration, ADL works
    auto it = find(str.begin(), str.end(), 'i');

    // error: why ADL doesn't work?
    std::shared_ptr<string> sp = make_shared<string>(str);
}
Run Code Online (Sandbox Code Playgroud)

当我试图编译这个程序时,编译器抱怨:

error: no template named 'make_shared'; did you mean 'std::make_shared'?
        std::shared_ptr<string> sp = make_shared<string>(str); // error...
                                     ^~~~~~~~~~~
                                     std::make_shared
Run Code Online (Sandbox Code Playgroud)

我猜第一个函数find不需要using声明,因为依赖于参数的lookup(ADL):编译器会搜索名称空间string(即std)的定义find.但对于第二个函数make_shared,它似乎ADL不起作用:我必须使用std::make_shared或 …

c++ templates function-templates argument-dependent-lookup

6
推荐指数
1
解决办法
331
查看次数

依赖于参数的查找在从另一个名称空间别名的类型上出现意外行为

我刚刚使用参数依赖查找遇到了一些有趣的行为,我不完全理解:

#include <iostream>

namespace a {
struct Foo {
  Foo(int v1, int v2) : v1(v1), v2(v2) { }
  int v1,v2;
};
}

namespace b {
template <typename T>
struct Baz : T {
  using T::T;
};
}

namespace c {
using Foo = ::b::Baz< ::a::Foo>;

// (1) NOT FOUND BY ADL
// std::ostream& operator << (std::ostream& os, const Foo& foo)
// {
//   return os << foo.v1 << "," << foo.v2;
// }
}

namespace b {

// (2) FOUND …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer argument-dependent-lookup

6
推荐指数
1
解决办法
93
查看次数

具有std :: function的ADL:是否可以通过std :: function的参数列表中的类型找到采用std :: function对象的函数?

考虑以下代码片段:

#include <functional>

namespace ns {
    struct Arg{};
    using Func = std::function<int(Arg)>;

    Func operator+(Func lhs, Func rhs) {
        return [lhs, rhs](Arg arg) {
            return lhs(arg) + rhs(arg);
        };
    }
}

int main() {
    ns::Func foo = [](ns::Arg i) {return 5;};
    ns::Func bar = [](ns::Arg i) {return 2;};
    auto foobar = foo + bar;
    return foobar(ns::Arg());
}
Run Code Online (Sandbox Code Playgroud)

上面的代码使用各种编译器进行编译。相反,以下代码段不会编译。唯一的区别是FuncArgvs int)内部使用的参数类型:

#include <functional>

namespace ns {
    using Func = std::function<int(int)>;

    Func operator+(Func lhs, Func rhs) {
        return [lhs, …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer argument-dependent-lookup std-function

6
推荐指数
1
解决办法
62
查看次数

ADL 对这段 C++ 代码有何影响?

实际上,使用此命令无法使用 Clang 编译以下代码:

clang++ -std=c++11 test.cc -o test.

我只想模仿与 C++ 中的“交换习语”相同的行为,以使用“使用指令”来启用 ADL。但是下面的代码我哪里错了?预期的呼叫优先级应该是:N1::foo> N2::foo> ::foo,对吗?

namespace N1 {
  struct S {};
  void foo(S s) {
    std::cout << "called N1::foo.";
  }
}
namespace N2 {
  void foo(N1::S s) {
    std::cout << "called N2::foo.";
  }
}
void foo(N1::S s) {
  std::cout << "called foo.";
}
int main() {
  using N2::foo;  
  foo(N1::S{});
}
Run Code Online (Sandbox Code Playgroud)

错误信息:

test.cc:54:3: error: call to 'foo' is ambiguous
  foo(N1::S{});
  ^~~
test.cc:40:8: note: candidate function
  void foo(S …
Run Code Online (Sandbox Code Playgroud)

c++ name-lookup argument-dependent-lookup

6
推荐指数
1
解决办法
77
查看次数

为什么C++ 11不支持这样的名称查找?

struct A
{
    enum InnerEnum { X };

    A(InnerEnum x)
    {}
};

int main()
{
    A a(X);
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨: error C2065: 'X' : undeclared identifier

编译器知道构造函数的参数类型是什么,因此当我将X作为参数传递时,编译器应该知道它是一个有效的参数.

我知道这不是ADL(Argument-dependent Name Lookup,也称为Koenig Lookup),但我认为它很有用且非常方便.因为我不必写如下:

A a(A::X);
Run Code Online (Sandbox Code Playgroud)

我认为ADL规则应该推广到这种情况.

我对吗?

c++ namespaces name-lookup argument-dependent-lookup c++11

5
推荐指数
1
解决办法
275
查看次数