gpt4 book ai didi

c++ - 三重符号 `&&&` 在 C++ 中代表什么?

转载 作者:行者123 更新时间:2023-11-30 02:51:45 39 4
gpt4 key购买 nike

我理解在类型名之后,单个 & 表示左值引用,而双 && 表示右值引用或“推导引用”,也称为universal reference斯科特迈耶斯。但我从未在函数或方法签名中看到过三重 &&&。它代表什么?

下面的代码生成一个带有三元组 &&& 的方法:

#include <iostream>
#include <utility>

template<typename ostream> void foo(ostream&& out) {
out << "foo" << std::endl;
}

template<typename ostream> void bar(ostream&& out) {
foo(std::forward<ostream>(out));
}

int main() {
bar(std::cout);
}

g++-4.8.1编译代码后,我运行nm -j a.out | C++过滤器-j 开关(我相信)是非标准的,它意味着只显示符号名称(没有值或类型)。我明白了:

__GLOBAL__sub_I_triple_ampersand.cpp
void bar<std::ostream&>(std::ostream&&&)
void foo<std::ostream&>(std::ostream&&&)
__static_initialization_and_destruction_0(int, int)
std::ostream::operator<<(std::ostream& (*)(std::ostream&))
std::ios_base::Init::Init()
std::ios_base::Init::~Init()
std::cout
std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
std::ostream&&& std::forward<std::ostream&>(std::remove_reference<std::ostream&>::type&)
std::piecewise_construct
std::__ioinit
std::basic_ostream<char, std::char_traits<char> >& std::operator<<<std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
___cxa_atexit
__mh_execute_header
_main
dyld_stub_binder

当我用 clang++ 编译时,我得到了类似的输出。所以我的问题是,三重符号代表什么?显然我不能直接在我的代码中写 &&& 。是因为我的 c++filt 对符号的分解不正确吗?我在 Mac OS X 10.8 上使用系统提供的 c++filt

最佳答案

  • 您将模板参数命名为 ostream 并使用 std::ostream& 对其进行实例化这一事实令人困惑。

  • 在 demangling 中有一个小错误(它应该用一个空格来打破 & 的组,因为它的意思是 & && 而不是 && & ),但是连续的 & 本身的存在不是问题:另一种分解名称的方法是 void bar<$T=std::ostream$&>($T$&&) ,即分解后的名称包含对参数的反向引用,而不是类型本身的扩展。

  • 为什么?通常,实例化的错位名称必须表示精确的实例化模板及其参数(而不是使用折叠规则或扩展对特征的引用等产生的签名)作为两个不同的同名函数模板的实例化在同一个签名中可以在一个程序中有效地共存(我不认为它们可以在一个编译单元中,但是名称查找和重载解析在 C++ 中非常复杂,我可能会弄错)并且使用简化的签名会不充分地合并它们.以及具有特征的示例,我目前无法想到具有引用折叠规则(*)的一个,后面的两个函数模板可能会在程序中重载(即使在同一个 CU 中)

    template <typename T>
    struct Traits{};

    template <typename T>
    void f(typename Traits<T>::T1)
    {
    return;
    }

    template <typename T>
    void f(typename Traits<T>::T2)
    {
    return;
    }

    但是如果你有以下特化的Traits

    template <>
    struct Traits<int> {
    typedef int T1;
    typedef int T2;
    };

    您不能在两者都可见的地方使用 f<int>(42),因为存在歧义,但是通过使它们有选择地可见,您可以在一个 CU 中使用一个,在另一个 CU 中使用另一个,因此 mangling 必须能够有所作为。

(*) 可能没有,我不记得曾提到过,一旦机制必须到位(另一个原因是限制损坏名称的大小),它更安全,也可能更容易继续将它用于所有事情。

关于c++ - 三重符号 `&&&` 在 C++ 中代表什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19510825/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com