首页 > 解决方案 > 带有 std::stringstream 的 C++ 模板特化

问题描述

我有这个玩具程序,它使用专门的C++模板:

#include <sstream>
#include <iostream>

class exception : public std::exception {
    public:
        std::string error;

        exception(std::string err) { error = err; }

        virtual const char* what() const throw() { return error.c_str(); };
};

template <class T = void>
class c_out {
    public:
        bool success = false;
        std::string error = "";
        T result;

        c_out<T> except(void) const {
            if (!success) { throw exception(error); };
            return *this;
        };
};

template <>
class c_out<std::stringstream> {
    public:
        bool success = false;
        std::string error = "";
        std::stringstream result;

        // Error handler
        c_out<std::stringstream> except(void) const {
            if (!success) { throw exception(error); };
            return std::move(*this);
        };
};

template <class T>
c_out<T> succeeded(T res) {
    c_out<T> outcome;
    outcome.success = true;
    outcome.result = res;
    return outcome;
};

c_out<std::stringstream> succeeded(std::stringstream& res) {
    c_out<std::stringstream> outcome;
    outcome.success = true;
    outcome.result = std::move(res);
    return outcome;
};

c_out<std::stringstream> foo(void) {
    std::stringstream ss;
    ss << 100 << ' ' << 200;
    return succeeded(ss);
}

int main (void) {
    auto X = foo().result;
    X.seekg(0, std::ios::end);
    return X.tellg();
}

但是,它因std::stringstream专业化而失败:

<source>: In member function 'c_out<std::__cxx11::basic_stringstream<char> > c_out<std::__cxx11::basic_stringstream<char> >::except() const':
<source>:36:35: error: use of deleted function 'c_out<std::__cxx11::basic_stringstream<char> >::c_out(const c_out<std::__cxx11::basic_stringstream<char> >&)'
   36 |             return std::move(*this);
      |                                   ^
<source>:27:7: note: 'c_out<std::__cxx11::basic_stringstream<char> >::c_out(const c_out<std::__cxx11::basic_stringstream<char> >&)' is implicitly deleted because the default definition would be ill-formed:
   27 | class c_out<std::stringstream> {
      |       ^~~~~~~~~~~~~~~~~~~~~~~~
<source>:27:7: error: use of deleted function 'std::__cxx11::basic_stringstream<_CharT, _Traits, _Alloc>::basic_stringstream(const std::__cxx11::basic_stringstream<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'
In file included from <source>:1:
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/sstream:787:7: note: declared here
  787 |       basic_stringstream(const basic_stringstream&) = delete;
      |       ^~~~~~~~~~~~~~~~~~

为什么?我应该如何使用except返回std::stringstream对象?

标签: c++templatesstringstream

解决方案


推荐阅读