macos — Что означает тройной амперсанд и & amp; & amp; `в C ++?

Я понимаю, что после typename, одного & означает ссылку lvalue и двойной && означает ссылку на значение или «выведенную ссылку», также называемую универсальная ссылка Скотт Мейерс. Но я никогда не видел тройной &&& в сигнатуре функции или метода. Что это значит?

Следующий код производит метод с тройным &&&:

#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++filt, -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 неправильно раскладывает символы? Я использую систему при условии c++filt в Mac OS X 10.8.

0

Решение

  • Тот факт, что вы называете свой параметр шаблона ostream и создать его с std::ostream& сбивает с толку.

  • Существует небольшая ошибка в раскладывании (она должна была поставить пробел, чтобы разбить группу & как его смысл & && и не && &), но наличие последовательного & Сами по себе не проблема: другим способом разоблачить имя было бы 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;
    }
    

    Но если у вас есть следующая специализация черт

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

    ты не можешь использовать f<int>(42) в месте, где оба видны, поскольку существует неоднозначность, но, делая их выборочно видимыми, вы можете использовать один в CU, а другой — в другом CU, так что искажение должно иметь возможность изменить ситуацию.

(*) Возможно, что нет ни одного, я не помню, чтобы кто-то упомянул упомянутое, и как только механизм должен быть на месте (другая причина — ограничение размера искаженных имен), это безопаснее и, вероятно, легче продолжать использовать его для всего.

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector