Получение операторов вставки ostream - PullRequest
1 голос
/ 19 июня 2019

У меня есть класс, который я хочу обернуть ostringstream.Я описал это следующим образом:

class Foo {
    ostringstream os;
public:
    template <typename T>
    decltype(ostream() << T(), Foo)& operator <<(const T& param) {
        os << param;
        return *this;
    }
}

Мое намерение состоит в том, что я получу любой оператор, определенный для ostream, бесплатно.Но я получаю ошибку компиляции:

ошибка C2893: Не удалось специализировать шаблон функции unknown-type &Foo::operator <<(const T &)

Я неправильно использую decltype или что-то в этом роде?

Ответы [ 2 ]

3 голосов
/ 19 июня 2019

std::ostream не имеет конструктора по умолчанию, а Foo не является выражением, которое можно использовать в decltype. Вместо этого вы можете напрямую использовать os в первом выражении. Чтобы легче вернуть Foo&, я бы использовал конечный тип возврата и использовал *this.

template <typename T>
auto operator<<(const T& param) -> decltype(os << param, *this);
2 голосов
/ 20 июня 2019

Это исключительно на основе ответа 0x499602D2 и вашей ссылки на отсутствующие перегрузки 10-12 .

Я не уверен, какие функции использоватьдля проверки перегрузки 11, но 10 и 12 проверяются с std::hex и std::endl.

#include <iomanip>
#include <iostream>
#include <sstream>

class Foo {
private:
    std::ostringstream os{};

public:
    using char_type = std::ostringstream::char_type;
    using traits_type = std::ostringstream::traits_type;

    // generic, with perfect forwarding instead of "const T&"
    template<typename T>
    auto operator<<(T&& param) -> decltype(os << std::forward<T>(param), *this) {
        os << std::forward<T>(param);
        return *this;
    }

    // overload 10
    Foo& operator<<(std::ios_base& (*func)(std::ios_base&)) {
        func(os);
        return *this;
    }

    // overload 11
    Foo& operator<<(std::basic_ios<char_type, traits_type>& (*func)(
        std::basic_ios<char_type, traits_type>&)) {
        func(os);
        return *this;
    }

    // overload 12
    Foo& operator<<(std::basic_ostream<char_type, traits_type>& (*func)(
        std::basic_ostream<char_type, traits_type>&)) {
        func(os);
        return *this;
    }

    auto str() { return os.str(); }
};

int main() {
    Foo a;

    a << "Hello Worl";      // generic
    a << std::hex << 13;    // 10 + generic
    a << std::endl;         // 12

    std::cout << a.str() << "\n";
}
...