2011-06-18 12 views
2

は、次のコードを考えてみてくださいそのコピーコンストラクタ呼び出し:は、テンプレート引数から派生し、

template<class basic_ios_type> 
class basic_ios_adaptor; 

template<template<typename, class> class basic_ios_type, typename char_type, class traits_type> 
class basic_ios_adaptor<basic_ios_type<char_type, traits_type>> 
    : public basic_ios_type<char_type, traits_type> 
{ 
public: 
    typedef basic_ios_type<char_type, traits_type> base_type; 

    basic_ios_adaptor(base_type const& other) 
     : base_type(other) 
    { 
    } 
}; 

のみ利用できるコンストラクタが基本型へのconst参照をとるコピーコンストラクタです。 使用例:

std::ofstream     x(std::ofstream("")); // ok 
basic_ios_adaptor<std::ofstream> y(std::ofstream("")); // error 

のVisual C++:

'のstd :: basic_ios < _Elem、_Traits> :: basic_ios' :クラス 「のstd :: basic_iosで宣言されたプライベートメンバー にアクセスすることはできません< _Elem、_Traits>」

インテル:

コンストラクタ のインスタンス "のstd :: basic_ofstream < _Elem、 _Traits> :: basic_ofstream [_Elem = CHAR、_Traits = STDとは:: char_traits]" 引数リスト

と一致する誰もが説明してもらえなぜ私はこれが機能していないのですか?

+0

ストリームのコピーとはどういう意味ですか?ストリームはコンテナではなく、データの流れです。 –

+1

@ Yochai Timmer - それはあなたのコーディング標準ではありません。 –

+0

@ Yochai:いいえ。大文字でクラス名を始めることはできません。大文字で始まるC++標準型を1つ指定します。 –

答えて

4

ストリームをコピーすることはできません。その理由は、そのコピーコンストラクタがプライベート(つまり、具体的にはbasic_iosのコピーctor)であるためです。

this questionも参照してください。

4

STLストリームをコピーすることはできません。あなたの問題です。

+0

なぜstd :: ofstreamで動作していますか? ( 'std :: ofstream x(std :: ofstream(" "))) – 0xbadf00d

+0

@ FrEEzE2046:そうではありません。あなたはコピーしていません。あなたの質問に対する私のコメントを参照してください。 –

0

私が達成したいのは、任意のbasic_ios <>クラスを作成する可能性です。だから、私の例では、指定されたファイルのforstreamを作成したかっただけです。

それは次のように可能です:

template<template<typename, class> class basic_ios_type, typename char_type, class traits_type> 
class basic_ios_adaptor<basic_ios_type<char_type, traits_type>> 
    : public basic_ios_type<char_type, traits_type> 
{ 
public: 
    typedef basic_ios_type<char_type, traits_type> base_type; 

    template<class create> 
    basic_ios_adaptor(create& create) 
    { 
     create(static_cast<base_type*>(this)); 
    } 
}; 

この段階では既に割り当てられて構成されているため、基本クラスへのポインタを渡すSAFTEであるべきです。

使用法:

struct construct 
{ 
    void operator()(std::ofstream* o) { 
     *o = std::ofstream("file"); 
    } 
}; 

construct c; 
basic_ios_adaptor<std::ofstream> y(c); 

その他の回避策?

+0

これは答えか質問ですか? –

+0

それはうまくいくので、答えです。しかし、これはコンパイラに依存しているかどうかによって異なります(私の最初の投稿のコメントを参照)。 – 0xbadf00d

+0

elisionに関する私のコメントは間違っていましたが、ストリームはまだコピーできません。私はあなたがここでやっていることは_moving_だと思います。これはC++ 0xの新機能です。あなたがそれを認識している限り、あなたのコードがそれを認識している限り、あなたは大丈夫かもしれません... –

1

前述したように、標準ストリームはコピー可能ではありません。ただし、C++ 0xでは、が移動可能です。どのコンパイラ/設定を使用しているかによって、表示されている動作が考えられます。 ofstream x(std::ofstream("x"));ofstreamの一時的なものを作成し、その一時的なものをofstreamという名前にします。これは完全に合法です。しかし、あなたのコードでは、コピーコンストラクタを定義しているので、移動は起こりません。コピーはまだ禁止されているので、コンパイラはあなたを止めます。

あなたのクラスでは、コピーではなく移動する必要があります。 ios_base_adaptor(base_type&& other) : ofstream(std::move(other)) { }

+0

これはまた、良い点と思われます。 – Xeo

関連する問題