是否可以使用ADL函数的地址? [英] Is it possible to take the address of an ADL function?

查看:144
本文介绍了是否可以使用ADL函数的地址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以采用通过ADL找到的函数的地址?

Is it possible to take the address of a function that would be found through ADL?

例如:

template<class T>
void (*get_swap())(T &, T &)
{
    return & _________;      // how do I take the address of T's swap() function?
}

int main()
{
    typedef some_type T;
    get_swap<T>();
}


推荐答案

老实说,我不知道,但我倾向于说这是不可能的。

Honestly, I don't know but I tend towards saying that this is not possible.

根据您要实现的目标,我可以建议一种解决方法。更精确地说,如果您只需要一个函数的地址与通过ADL调用 swap 相同的语义,则可以使用以下地址:

Depending on what you want to achieve I can suggest a workaround. More precisely, if you just need the address of a function that has the same semantics as swap called through ADL then you can use this:

template <typename T>
void (*get_swap())(T&, T&) {
    return [](T& x, T& y) { return swap(x, y); };
}

例如,以下代码:

namespace a {

  struct b {
      int i;
  };

  void swap(b& x, b& y) {
      std::swap(x.i, y.i);
  }
}

int main() {

    auto f0 = (void (*)(a::b&, a::b&)) a::swap;
    auto f1 = get_swap<a::b>();

    std::cout << std::hex;
    std::cout << (unsigned long long) f0 << '\n';
    std::cout << (unsigned long long) f1 << '\n';
}

使用gcc 4.8.1编译( -std =我的机器上的c ++ 11 -O3 )给出了:

compiled with gcc 4.8.1 (-std=c++11 -O3) on my machine gave:

4008a0
4008b0

相关的汇编代码( objdump -dSC a.out )是

00000000004008a0 <a::swap(a::b&, a::b&)>:
  4008a0:   8b 07                   mov    (%rdi),%eax
  4008a2:   8b 16                   mov    (%rsi),%edx
  4008a4:   89 17                   mov    %edx,(%rdi)
  4008a6:   89 06                   mov    %eax,(%rsi)
  4008a8:   c3                      retq   
  4008a9:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000004008b0 <void (*get_swap<a::b>())(a::b&, a::b&)::{lambda(a::b&, a::b&)#1}::_FUN(a::b&, a::b&)>:
  4008b0:   8b 07                   mov    (%rdi),%eax
  4008b2:   8b 16                   mov    (%rsi),%edx
  4008b4:   89 17                   mov    %edx,(%rdi)
  4008b6:   89 06                   mov    %eax,(%rsi)
  4008b8:   c3                      retq   
  4008b9:   0f 1f 80 00 00 00 00    nopl   0x0(%rax)

可以看到 f0 f1 (位于 0x4008a0 0x4008b0 中,分别)是二进制相同的。用clang 3.3编译时也是如此。

As one can see the functions pointed by f0 and f1 (located at 0x4008a0 and 0x4008b0, respectively) are binary identical. The same holds when compiled with clang 3.3.

如果链接器可以进行相同的COMDAT折叠(ICF),我想我们甚至可以得到 f0 == f1 。 (有关ICF的更多信息,请参见帖子。)

If the linker can do identical COMDAT folding (ICF), I guess, we can even get f0 == f1. (For more on ICF see this post.)

这篇关于是否可以使用ADL函数的地址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆