Перегрузка времени компиляции для оператора ostream - PullRequest
1 голос
/ 21 сентября 2019

Я пытаюсь ввести механизм перегрузки, основанный на ранге объекта.Мне удалось реализовать простой пример на основе другого сообщения, и он работает для простых типов: https://coliru.stacked -crooked.com / a / 8129de0ae8a71af1

Теперь я хотел бысделать что-то подобное для пользовательского типа:

#include <iostream>
#include <type_traits>
#include <sstream>

class Foo {
};

template < class T,
               typename std::enable_if <(std::rank<T>::value == 0), int>::type = 0 >
    void f(std::ostream& os, const T& value)
    {
        os << "rank: 0" << std::endl;
    }

    template< class T,
             typename std::enable_if<(std::rank<T>::value == 1), int>::type = 0 >
    void f(std::ostream& os, const T& value)
    {
        os << "rank: 1" << std::endl;
    }

    template <class T>
    std::ostream& operator<<(std::ostream& os, const T& foo)
    {
        f<decltype(foo)>(os, foo);
        return os;
    }

int main()
{
    Foo foo0;
    Foo foo1[5];

    //std::cout << std::rank<decltype(foo0)>{} << "\n"; // 0
    //std::cout << std::rank<decltype(foo1)>{} << "\n"; // 1

    // correct
    f<decltype(foo0)>(std::cout, foo0); //prints: rank: 0
    f<decltype(foo1)>(std::cout, foo1); //rank: 1

    // invalid
    std::cout << foo0; //prints: rank: 0
    std::cout << foo1; //rank: 0

    return 0;
}

https://coliru.stacked -crooked.com / view? id = cf91cec14a111f70

Когда я вызываю функции напрямую, яЯ получаю действительные результаты, но когда я делаю это по << каждый раз, когда я получаю 0. Не могли бы вы объяснить, что я делаю неправильно?</p>

1 Ответ

1 голос
/ 21 сентября 2019

Вам не нужно использовать decltype здесь, просто используйте T:

template<class T>
std::ostream& operator<<(std::ostream& os, const T& foo)
{
    f< T >(os, foo);
    return os;
}

, но при использовании decltype вам придется удалить ссылку из foo типа:

template<class T>
std::ostream& operator<<(std::ostream& os, const T& foo)
{
    f< std::remove_reference_t< decltype(foo) > >(os, foo);
    return os;
}

Когда вычитание типа шаблона работает, T определяется как Foo [5] - что поддерживает rank.Но когда вы делаете decltype(foo), он возвращает тип также с const & - так что у вас есть const Foo (&)[4].rank потому что эта штука просто не работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...