标签: argument-dependent-lookup

为什么“xxx::function();” 不起作用,但“使用名称空间 xxx; function();” 做?

我正在使用 Boost 的图 C++ 库,在询问网格图的顶点数时我偶然发现了一个问题。

\n

下面的代码片段创建了一个形状为 5 x 6 的二维网格图,然后打印该图的顶点数,即5x6 = 30。\n但是,这不会编译并出现错误:

\n
\n

错误:\xe2\x80\x98num_vertices\xe2\x80\x99 不是 \xe2\x80\x98boost\xe2\x80\x99 的成员

\n
\n
#include <boost/graph/grid_graph.hpp>\n#include <iostream>\n\nint main()\n{\n    typedef boost::grid_graph<2> Graph;\n    Graph g({5, 6});\n    std::cout << "Num vertices: " << boost::num_vertices(g) << std::endl;\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如果我将代码更改为包含using namespace boost;在开头,那么它确实有效:

\n
#include <boost/graph/grid_graph.hpp>\n#include <iostream>\n\nusing namespace boost;\n\nint main()\n{\n    typedef grid_graph<2> Graph;\n    Graph g({5, 6});\n    std::cout << "Num vertices: " << num_vertices(g) << std::endl;\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

奇怪的是,当我使用不同的 Boost 图类型(例如boost::adjacency_list<>. …

c++ boost namespaces boost-graph argument-dependent-lookup

3
推荐指数
1
解决办法
338
查看次数

在C++中解析函数/方法/模板名称的偏好是什么?

如果有多种可能性,C++编译器如何决定调用哪个函数/方法?在我的具体情况下,我有C++运行时的标准自由函数,我也有一个模板化的免费变体,如下所示:

// The definitions of the C++ Run Time Library (from memory.h)
extern malloc(size_t s);
extern void free(void *p);

// Our own memory management functions
extern void *OurMalloc(size_t s);
extern void OurFree(void *p);

// Own variants to overrule malloc and free (instead of using #define)
template<typename T>
void *malloc(T t)
{
return OurMalloc(t);
}

template<typename T>
void free(T *t)
{
OurFree(t);
}
Run Code Online (Sandbox Code Playgroud)

我使用以下代码测试了这个:

void main(void)
{
void *p = malloc(10);
free(p);
}
Run Code Online (Sandbox Code Playgroud)

如果我编译并运行它,似乎对malloc的调用被模板化变量正确替换.到现在为止还挺好.

但是,对free的调用不会被模板化变量所取代,并且仍会调用标准C++函数.

C++编译器使用什么规则来决定哪个变体优先?这与Koenig查找规则有关吗?

注意:我尝试了这种替代方法,因为使用#define无法解决问题(请参阅问题如何使用C宏(#define)来改变调用而不是原型).

c++ templates argument-dependent-lookup

2
推荐指数
1
解决办法
436
查看次数

C++ 11样式SFINAE和模板实例化时的函数可见性

我不确定这与sfinae有什么关系,或者只是与任何模板化函数相关的东西.我试图使用sfinae根据相应的自由函数的存在启用/禁用成员函数,而后者又基于另一种类型的成员函数的存在而启用/禁用,所有使用此处描述的方法:

struct S;

template <typename T>
inline auto f(S& s, T const& t)
   -> decltype(t.f(s), void())
{
   t.f(s);
}

struct S
{
    template <typename T>
    auto f(T const& t)
        -> decltype(f(*this, t), void())
    {
        f(*this, t); // <------------------------------------------- HERE
    }
};

struct pass
{
    void f(S&) const
    {
        //...
    }
};

struct fail
{
};

int main()
{
    S s;
    s.f(pass()); // should compile fine
    //s.f(fail()); // should fail to compile due to absence of f from S …
Run Code Online (Sandbox Code Playgroud)

c++ templates sfinae argument-dependent-lookup c++11

2
推荐指数
1
解决办法
958
查看次数

尾随返回类型中的名称查找问题

以下示例说明了我的问题:

#include <iostream>
#include <string>

template <typename T>
auto func(const T& x) -> decltype(to_string(x)) {
  using std::to_string;
  return to_string(x);
}

int main() {
  std::cout << func(1);
}
Run Code Online (Sandbox Code Playgroud)

我不想导入std::to_string全局命名空间,我不想-> decltype(std::to_string(x))这样做,因为这样做会禁用ADL.很显然,你不能把using std::to_stringdecltype.那么,我该怎么做呢?

c++ template-meta-programming argument-dependent-lookup trailing-return-type c++14

2
推荐指数
1
解决办法
68
查看次数

在ostream和operator <<中键入转换

我有一个课程entry并且被ostream& operator <<覆盖了.我还有一个辅助类cursor和一个类型转换operator entry().然后,在我的main()函数中,我有以下表达式:

cout << data[4];
Run Code Online (Sandbox Code Playgroud)

这里data[4]是一个cursor,但编译失败

错误:二进制表达式的操作数无效

我想要的是编译器转换data[4]entry和使用它的<<运算符.有没有办法以上述方式调用此ostream运算符而无需添加特殊方法entry

以下是一些代码:

    class entry
    {
        friend class cursor;
        /*here comes some data*/

    public:    

        friend ostream& operator << (ostream& out, const entry& a);
    };
Run Code Online (Sandbox Code Playgroud)

    class cursor
    {
        database* data_;
        size_t ind_;
        friend class entry;
        friend class database;

    public:
        cursor (database* a, size_t ind);
        cursor (const cursor& a);
        void operator= (const …
Run Code Online (Sandbox Code Playgroud)

c++ operator-overloading friend-function argument-dependent-lookup

2
推荐指数
1
解决办法
63
查看次数

C++ Koenig(Argument-Dependent)查找:如果不同名称空间中的两个名称空间函数具有相同的参数类型,该怎么办?

如果有的话会发生什么

Foo::test(Foo::A &a, Bar::B &b, C &c); 和a

Bar::test(Foo::A &a, Bar::B &b, C &c);.

参数的名称空间是否由编译器按顺序考虑(第一个参数优先于参数依赖查找),或者这被认为是不明确的?

c++ argument-dependent-lookup

2
推荐指数
1
解决办法
47
查看次数

函数查找和命名空间

如果在调用它的作用域中找不到函数,则会查找其参数的名称空间.我有几个问题.

  1. 如果在不同的命名空间中有多个参数,首先会查找哪个命名空间?它是第一个参数的命名空间吗?

    f(A::T t, B:U u); // Is namespace A looked up first?
    
    Run Code Online (Sandbox Code Playgroud)
  2. 模板类更复杂,比如

    f(A::T<B::U> t); // Namespace A or B is looked up first?
    
    Run Code Online (Sandbox Code Playgroud)

c++ namespaces argument-dependent-lookup

2
推荐指数
1
解决办法
180
查看次数

类内定义的友元函数的调试标志中的命名空间

我正在处理一个类,该类在没有外部声明的情况下在类中定义了友元函数

namespace our_namespace {
template <typename T>
struct our_container {

  friend our_container set_union(our_container const &, our_container const &) {
    // meaningless for the example here, just a valid definition
    // no valid semantics
    return our_container{};
  }
};
}  // namespace our_namespace
Run Code Online (Sandbox Code Playgroud)

正如所讨论的(例如此处此处),函数set_union不在our_namespace命名空间中,但可以通过参数依赖查找找到:

auto foo(std::vector<our_namespace::our_container<float>> in) {
  // works:
  return set_union(in[0], in[1]);
}
Run Code Online (Sandbox Code Playgroud)

但是我注意到,调试标志中 set_union似乎是在our_namespace命名空间中

        mov     rdi, qword ptr [rbp - 40] # 8-byte Reload
        mov     rsi, rax
        call …
Run Code Online (Sandbox Code Playgroud)

c++ friend-function argument-dependent-lookup

2
推荐指数
1
解决办法
39
查看次数

为什么 ADL 不适用于在命名空间之外定义的函数?

我知道我的编译器在下面的例子中将执行函数First::fun(),因为参数相关的名称查找 (ADL)/Koenig 查找并且为了执行Second::fun()它需要在main函数中显式调用。

#include <iostream>
using namespace std;

namespace First
{
    enum Enum
    {
        FIRST
    };

    void fun(First::Enum symbol)
    {
        cout << "First fun\n";
    }
}

namespace Second
{
    void fun(First::Enum symbol)
    {
        cout << "Second fun\n";
    }
}

int main()
{
    fun(First::FIRST);  // Calls First::fun()
}
Run Code Online (Sandbox Code Playgroud)

但是,当fun()在命名空间之外添加另一个函数(请参阅下面的代码)并在fun()没有前缀命名空间的情况下调用时,编译器会给出歧义错误。命名空间内的函数仍然可以通过显式添加命名空间前缀来调用,但fun()无法访问。当没有显式调用时,为什么编译器不喜欢命名空间之外的函数?是否有避免这种行为的具体原因?

// ^ Namespaces are still here

fun(First::Enum symbol)
{
    cout << "No namespace fun\n";
}    

int main()
{
    fun(First::FIRST);  // …
Run Code Online (Sandbox Code Playgroud)

c++ argument-dependent-lookup

2
推荐指数
1
解决办法
49
查看次数

为什么这个函数调用没有拒绝不合适的重载?

考虑以下代码:

#include<vector>
#include<ranges>
#include<algorithm>
//using namespace std;
using namespace std::ranges;
int main()
{
    std::vector<int> a = {};
    sort(a);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它运行正常。

显然,它调用了这个重载函数(函子,严格来说):

template<random_access_range _Range,
     typename _Comp = ranges::less, typename _Proj = identity>
  requires sortable<iterator_t<_Range>, _Comp, _Proj>
  constexpr borrowed_iterator_t<_Range>
  operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
  {
return (*this)(ranges::begin(__r), ranges::end(__r),
           std::move(__comp), std::move(__proj));
  }
Run Code Online (Sandbox Code Playgroud)

但是在我们引入命名空间 std 后,函数调用变得不明确(出现编译错误):

#include<vector>
#include<ranges>
#include<algorithm>
using namespace std;
using namespace std::ranges;
int main()
{
    std::vector<int> a = {};
    sort(a);
    return 0;
} …
Run Code Online (Sandbox Code Playgroud)

c++ overloading sfinae overload-resolution argument-dependent-lookup

2
推荐指数
1
解决办法
90
查看次数