标签: argument-dependent-lookup

自定义容器迭代器是否保证ADL考虑命名空间std?

我无意在实际代码中使用它.我承诺.

std当函数参数是类型container::iteratorcontainer::iterator不是typedef内置类型时,标准是否保证找到命名空间?

例如

#include <set>
#include <algorithm>
int main()
{
   std::set<int> s;
   find(s.begin(), s.end(), 0); //do I have a guarantee that std::find will be found?
}
Run Code Online (Sandbox Code Playgroud)

换句话说,迭代器类是否可以在stdADL不考虑的命名空间中定义?

提前致谢.

c++ iterator stl std argument-dependent-lookup

7
推荐指数
2
解决办法
174
查看次数

C++中依赖于参数的查询

这是如何运作的?它与ADL有关吗?

#include <iostream>

template <typename T>
struct A
{
    friend void f(T x)
    {
        std::cout << "A\n";
    }
};

int main()
{
    f(new A<void*>());
}
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我为什么我不能使用类似的东西

f(A<int>());
Run Code Online (Sandbox Code Playgroud)

c++ argument-dependent-lookup

7
推荐指数
1
解决办法
2407
查看次数

ADL不查找静态成员函数吗?

这是来自依赖参数的查询的后续问题,只搜索名称空间或类吗?,其中@DavidRodríguez说"ADL将查看该类型的封闭命名空间,以及类型本身内部 ".我可能错了他想说的但是我试着这个例子:

struct foo{
    static void bar(foo* z){}    
};

int main(){
    foo* z;
    bar(z);
}
Run Code Online (Sandbox Code Playgroud)

它没有编译,产生错误"'bar'未在此范围内声明".是不是ADL不考虑静态成员函数?我的意思是在示例中关联类是foo不是ADL看起来在类中?.任何人都可以在这里简化规则吗?

c++ argument-dependent-lookup

7
推荐指数
1
解决办法
447
查看次数

为什么'std :: endl'在语句'std :: cout << std :: endl;"中使用时需要命名空间限定,给定参数依赖查找?

我正在查看关于参数依赖查找的维基百科条目,并且(2014年1月4日)给出了以下示例:

#include<iostream>

int main() 
{
  std::cout << "Hello World, where did operator<<() come from?" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

......有以下评论:

请注意,std :: endl是一个函数,但它需要完全限定,因为它被用作operator <<的参数(std :: endl是函数指针,而不是函数调用).

我的想法是评论不正确(或根本不清楚).我正在考虑更改评论,而不是

请注意,std :: endl需要完全限定,因为ADL不适用于函数调用的参数 ; 它只适用于函数名称本身.

我是否认为维基百科的评论不正确?我建议的改变是否正确?(即,在这个例子中,我对ADL的理解是正确的吗?)

c++ argument-dependent-lookup

7
推荐指数
1
解决办法
377
查看次数

可以放"使用std :: swap;" 在标题?

我已经读过,当你使用swapc ++时,你应该总是using std::swap;,然后调用swap不合格,所以它会自动选择std::那些std::和内置类型,自定义类型的自定义类型,以及std::其他所有类型的模板类型.

那么,我可以只放入using std::swap;每个文件包含的标题而不必担心它吗?

我明白避免using在标题中是常见的做法.但是,在这种特殊情况下它有问题吗?

c++ namespaces argument-dependent-lookup

7
推荐指数
1
解决办法
205
查看次数

围绕功能调用解决方案的混乱

这个问题的灵感来自于这个问题.考虑一下代码:

namespace ns {
  template <typename T>
  void swap(T& a, T& b) {
    using namespace std;
    swap(a, b);
  }
}
Run Code Online (Sandbox Code Playgroud)

在使用GCC进行一些测试后,我发现swap(a, b);解析为
1)std::swap如果T已经过载std::swap(例如,标准容器类型)
2)ns::swap否则,导致无限递归.
因此,似乎编译器将首先尝试在命名空间中找到匹配项ns.如果找到匹配项,则搜索结束.但是当ADL进入时并非如此,在这种情况下,std::swap无论如何都会找到.解决过程似乎很复杂.

我想知道swap(a, b)在上面的上下文中解析函数调用过程中发生了什么的细节.可以参考该标准.

c++ function-calls language-lawyer overload-resolution argument-dependent-lookup

7
推荐指数
1
解决办法
161
查看次数

对于朋友函数的依赖于参数的查找

考虑以下:

namespace N {
    struct A { };

    struct B {
        B() { }
        B(A const&) { }
        friend void f(B const& ) { }
    };
}

int main() {
    f(N::B{}); // ok
    f(N::A{}); // error
}
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,案例成功 - 我们考虑相关的名称空间N::B和查找N::f(B const&).大.

第二种情况失败了.为什么?根据[namespace.memdef]:

如果friend非本地类中的声明首先声明了类,函数,类模板或函数模板,则该友元是最内层封闭命名空间的成员.[...]如果调用了友元函数或函数模板,则可以通过名称查找找到其名称,该名称查找考虑名称空间中的函数和与函数参数类型相关联的类(3.4.2).

的关联的命名空间N::AN,它的f一个成员,所以为什么不通过查找发现的?

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

7
推荐指数
1
解决办法
352
查看次数

如果类型来自std,是否可以创建一个特征来回答?

在使用ADL解决这个问题后,如果传递的类型来自我们的命名空间,则可以创建一个特征来回答:

#include <utility>

namespace helper
{
  template <typename T, typename = void>
  struct is_member_of_sample : std::false_type
  {
  };

  template <typename T>
  struct is_member_of_sample<
      T,
      decltype(adl_is_member_of_sample(std::declval<T>()))> : std::true_type
  {
  };
}

namespace sample
{
  template <typename T>
  auto adl_is_member_of_sample(T && ) -> void;
}

// -- Test it

namespace sample
{
  struct X;
}

struct Y;

static_assert(helper::is_member_of_sample<sample::X>::value, "");
static_assert(not helper::is_member_of_sample<Y>::value, "");

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

由于显而易见的原因,这不能应用于std命名空间 - 根本没有办法将adl_is_member_of_sample等效命令注入std命名空间而不将自己暴露给未定义的行为.

是否有一些解决方法可以创建特征?

c++ templates type-traits argument-dependent-lookup c++11

7
推荐指数
1
解决办法
312
查看次数

ADL在constexpr函数中不起作用(仅适用于clang)

以下代码使用MSVC和gcc进行编译,但不能使用clang进行编译。为什么?

如果CallFoo ()is的话,似乎ADL无法正常工作constexpr。查看评论。

template <class T>
constexpr void CallFoo  ()          // Remove constexpr to fix clang compilation error.
{
    Foo (T ());
}


class Apple {};


int main ()
{
    CallFoo<Apple> ();
}


constexpr void Foo (Apple)
{
}
Run Code Online (Sandbox Code Playgroud)

Clang错误消息(请参阅godbolt.org):

<source>:4:5: error: use of undeclared identifier 'Foo'
    Foo (T ());
    ^
<source>:13:5: note: in instantiation of function template specialization 'CallFoo<Apple>' requested here
    CallFoo<Apple> ();
    ^
Run Code Online (Sandbox Code Playgroud)

c++ templates clang argument-dependent-lookup constexpr

7
推荐指数
1
解决办法
92
查看次数

基于参数的依赖名称查找

在cppreference.com上的描述

模板中使用的从属名称的查找被推迟到知道模板参数为止,这时ADL会检查具有外部链接的函数声明,这些声明从模板定义上下文模板实例化上下文中可见。

与此相反,以下代码片段可以使用三个编译器(MSVC,clang和gcc)很好地进行编译:

template <class T>
void CallFoo ()
{
    Foo (T ());
}


class Apple {};


int main ()
{
    CallFoo<Apple> ();
}


static void Foo (Apple)
{
}
Run Code Online (Sandbox Code Playgroud)

Foo是以下内容中的从属名称CallFoo:它取决于模板参数T。但是,Foo尽管违反了上面引用的两个规则,但是编译器仍然可以找到该函数。

  • Foo从的定义或实例中都看不到的声明CallFoo,因为它位于两者之下。
  • Foo 有内部联系。

这三个编译器都不可能有错误。我可能误会了一些东西。您能详细说明一下吗?

c++ linkage dependent-name language-lawyer argument-dependent-lookup

7
推荐指数
1
解决办法
126
查看次数