13077


コンソールAPPを途中まで作り、ビルドできるかためしたところ、下記のようなエラーが残ったのですが、意味がよくわかりません。

[code]

    In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/ios:42:0,
                     from /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/istream:38,
                     from /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/sstream:38,
                     from stdafx.h:11,
                     from OperationService.cpp:1:
    /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/bits/ios_base.h: コピーコンストラクタ ‘std::basic_ios::basic_ios(const std::basic_ios&)’ 内:
    /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/bits/ios_base.h:786:5: エラー: ‘std::ios_base::ios_base(const std::ios_base&)’ は非公開です
         ios_base(const ios_base&);
         ^
    In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/ios:44:0,
                     from /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/istream:38,
                     from /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/sstream:38,
                     from stdafx.h:11,
                     from OperationService.cpp:1:
    /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/bits/basic_ios.h:66:11: エラー: within this context
         class basic_ios : public ios_base
               ^
    In file included from stdafx.h:11:0,
                     from OperationService.cpp:1:
    /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/sstream: コピーコンストラクタ ‘std::basic_stringstream::basic_stringstream(const std::basic_stringstream&)’ 内:
    /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/sstream:502:11: 備考: synthesized method ‘std::basic_ios::basic_ios(const std::basic_ios&)’ first required here
         class basic_stringstream : public basic_iostream
               ^
    In file included from /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/ios:43:0,
                     from /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/istream:38,
                     from /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/sstream:38,
                     from stdafx.h:11,
                     from OperationService.cpp:1:
    /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/streambuf: コピーコンストラクタ ‘std::basic_stringbuf::basic_stringbuf(const std::basic_stringbuf&)’ 内:
    /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/streambuf:802:7: エラー: ‘std::basic_streambuf::basic_streambuf(const std::basic_streambuf&) [with _CharT = char; _Traits = std::char_traits]’ は非公開です
           basic_streambuf(const basic_streambuf& __sb)
           ^
    In file included from stdafx.h:11:0,
                     from OperationService.cpp:1:
    /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/sstream:64:11: エラー: within this context
         class basic_stringbuf : public basic_streambuf
               ^
    /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/sstream: コピーコンストラクタ ‘std::basic_stringstream::basic_stringstream(const std::basic_stringstream&)’ 内:
    /usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++/sstream:502:11: 備考: synthesized method ‘std::basic_stringbuf::basic_stringbuf(const std::basic_stringbuf&)’ first required here
         class basic_stringstream : public basic_iostream
               ^
    OperationService.cpp: メンバ関数 ‘std::stringstream OperationService::createJA()’ 内:
    OperationService.cpp:39:9: 備考: synthesized method ‘std::basic_stringstream::basic_stringstream(const std::basic_stringstream&)’ first required here
      return ss;
             ^
    
[/code]

C++開発は2度目(以前もコンソールアプリケーションを作成しました。)  
ほとんど実装は以前のものの流用ですが、以前はビルドできました。

ios_baseが公開されていないとのことなので、fstreamの部分が悪いのかと思い、いろいろいじってみましたがうまくいきません。

以下、おそらくエラーの該当クラスです。

[code]

    #include "stdafx.h"
    #include "OperationService.h"
    #include "DomParser.h"
    
    using namespace std;
    
    #define ASSERT_JA "~/.base_ja"
    #define ASSERT_EN "~/.base_en"
    
    #define MIGR_JA "~/.mig_ja"
    #define MIGR_EN "~/.mig_en"
    
    /**
    * Migrationの英語版
    **/
    stringstream OperationService::createEN() {
        stringstream ss;
        ss <<  略
        ss << "Before January 8th, 2014" << endl;
        return ss;
    }
    
    /**
    * Migrationの日本語版
    **/
    stringstream OperationService::createJA() {
        stringstream ss;
        ss << 略
        ss << "1.0が破棄されると、XMPPサービスおよびAPIは利用できなくなります。" << endl;
        return ss;
    }
    
    /**
     * diff
     **/
    void OperationService::diff() {
    
        cout << "====================== diffedence check start =========================" << endl;
    
        fstream ifs;
        DomParser domParser;
    
        // 日本語正規ドキュメント作成
        ifs.open(ASSERT_JA, ios::in);
        if (!ifs) {
                ifs.close();
                ifs.open(ASSERT_JA, ios::out);
                ifs << createJA().str() << endl;
                ifs.close();
        }
    
        // 英語正規ドキュメント作成
        ifs.open(ASSERT_EN, ios::in);
        if (!ifs) {
                ifs.close();
                ifs.open(ASSERT_EN, ios::out);
                ifs << createEN().str() << endl;
                ifs.close();
        }
    
        stringstream ss;
    
        // 英語HTML取得
        ss << "wget https://dummy/migrations -O " << MIGR_EN << endl;
        system(ss.str().c_str());
        ss.clear();
    
        // 日本語HTML取得
        ss << "wget https://dummy/migrations?locale=ja_JP -O " << MIGR_JA << endl;
        system(ss.str().c_str());
        ss.clear();
    
        // 日本語MigrationTEXT抽出
        {
                xmlDocPtr doc = domParser.parse(MIGR_JA);
                xmlNodeSetPtr nodeSet = domParser.executeXpath(doc, (xmlChar *)"//./text()");
                string content = (char*)xmlXPathNodeSetItem(nodeSet, 0)->content;
                ifs.open(MIGR_JA, ios::out | ios::trunc);
                ifs << content << endl;
                ifs.close();
        }
    
        // 英語MigrationTEXT抽出
        {
                xmlDocPtr doc = domParser.parse(MIGR_EN);
                xmlNodeSetPtr nodeSet = domParser.executeXpath(doc, (xmlChar *)"//./text()");
                string content = (char*)xmlXPathNodeSetItem(nodeSet, 0)->content;
                ifs.open(MIGR_EN, ios::out | ios::trunc);
                ifs << content << endl;
                ifs.close();
        }
    
        // 比較実行 日本語
        cout << "--------- Japanese ----------" << endl << endl << endl;
        ss << "diff -Bt " << ASSERT_JA << " " << MIGR_JA;
        system(ss.str().c_str());
        ss.clear();
    
        // 比較実行 英語
        cout << "--------- English ----------" << endl << endl << endl;
        ss << "diff -Bt " << ASSERT_EN << " " << MIGR_EN;
        system(ss.str().c_str());
        ss.clear();
    }
    
[/code]


CC BY-SA 3.0
2015-08-05T11:57:34.887
13074
2015-08-06T07:27:36.820
8396
question
c++
C++のios_baseが公開されていないといわれる


[Return stringstream from a
function](https://stackoverflow.com/questions/5119963/return-stringstream-
from-a-function) などを読みますと、C++ では stream オブジェクトをコピーすることができない様ですね。

リンク先にも書いてある様に、`return ss.str()` として `std::string` を返す様にすると良いかと思います。

**※ yoh2 さんのご指摘を受けて以下を削除します。**  
~~  
以下の様にして stringstream オブジェクトへのポインタを返す様にすれば良いかと思います。

[code]

    stringstream* OperationService::createEN() {
      stringstream* ss = new(stringstream);
      *ss <<  略
      *ss << "Before January 8th, 2014" << endl;
      return ss;
    }
                    :     
    
    ifs << createEN()->str() << endl;
    
[/code]

~~


CC BY-SA 3.0
2015-08-05T13:06:03.220
13077
2015-08-05T15:37:46.540
2017-05-23T12:38:55.307
-1
13074
answer


`stringstream`はコピー不可能なオブジェクトのため、C++03までは関数の戻り値型を`stringstream`とするのはおすすめしません。

C++11以降では、`stringstream`がムーブ可能なオブジェクトに拡張されたため、そのままのコードでもコンパイルできると思います。

[code]

    // C++11以降
    stringstream some_function() {
        stringstream ss;
        ss << ...;
        return ss;  // (暗黙に)ムーブで関数戻り値を返す
    }
    
[/code]

* * *

> OperationService.cpp: メンバ関数 ‘std::stringstream OperationService::createJA()’
> 内:  
>  OperationService.cpp:39:9: 備考: synthesized method
> ‘std::basic_stringstream::basic_stringstream(const
> std::basic_stringstream&)’ first required here  
>  return ss;

エラーメッセージの末尾付近に直接的な原因箇所：メンバ関数`OperationService::createJA()`の`return
ss;`に問題があることが示されています。

「ios_baseで非公開が云々」という理解しづらいエラーメッセージになる理由は、次の通りです。

  * オブジェクトをコピーするときは、対象クラス(`stringstream`)のコピーコンストラクタが呼ばれる。
  * コピーコンストラクタでは、全ての基底クラス(`ios_base`, `ios`, `istream`, `ostream`, `iostream`)のコピーコンストラクタを呼び出す。
  * 全てのコピーコンストラクタは、クラスの外からアクセス可能(`public`)でなければいけない。
  * C++03では「コピー不可能なクラス」を表現する方法として、「コピーコンストラクタを非公開(`private`)にしておく」しか手段がなかった。
  * コピー不可能クラスのオブジェクトを、ユーザコードが誤ってコピー操作すると「基底クラスのコピーコンストラクタが非公開」という一見すると謎なコンパイルエラーになる。


CC BY-SA 3.0
2015-08-06T07:27:36.820
13102
2015-08-06T07:27:36.820
49
13074
answer