2013-02-20 6 views
6

3つの値を持つ構造体を作成したい:文字列と2つのint。文字列は必須ですが、intのどちらか(または両方)はオプションです。指定されていない場合、デフォルトは-1になります。タプルから派生したオブジェクトをC++のベクトルに配置する

しかし、構造体を使用するのではなく、私はstd :: tupleを試してみると思いました。 2つのint、IセットアップSTDから継承「トリオ」クラス::タプルのオプションネスを組み込むためには以下のように:それから私はいくつかのトリオのオブジェクトを押すことでトリオクラスをテストするために行く

#include <string> 
#include <tuple> 

class Trio : public std::tuple<std::string, int, int> 
{ 
    public: 

    explicit Trio(std::string const & name, int val1 = -1, int val2 = -1) 
    : 
     tuple(name, val1, val2) 
    { 
    } 
}; 

std ::ベクトルへ:

#include <vector> 
int main(void) 
{ 
    std::vector<Trio> trios; 

    Trio trio("trio1", 1, 1); 
    trios.push_back(trio); 

    return 0; 
} 

それは私のVisual Studio 2010で次のエラー得られます

>c:\program files (x86)\microsoft visual studio 10.0\vc\include\tuple(127): 
    error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(const 
    std::basic_string<_Elem,_Traits,_Ax> &)' : cannot convert parameter 1 
    from 'const Trio' to 'const std::basic_string<_Elem,_Traits,_Ax> &' 
with 
[ 
    _Elem=char, 
    _Traits=std::char_traits<char>, 
    _Ax=std::allocator<char> 
] 
Reason: cannot convert from 'const Trio' to 'const 
std::basic_string<_Elem,_Traits,_Ax>' 
with 
[ 
    _Elem=char, 
    _Traits=std::char_traits<char>, 
    _Ax=std::allocator<char> 
] 
No user-defined-conversion operator available that can perform 
this conversion, or the operator cannot be called 

を誰も私が間違ってここにやっているかを理解していますか?私が見ていないだけの何かがありますか?私はおそらく、厳密にstd :: tupleの使用法を乱用していますか?

は、

アーロン

+0

ideoneでOK: – Bill

+0

これはg ++で私のためにコンパイルされています。http://ideone.com/ZAIDUp – juanchopanza

答えて

8

これはVC30のバグです。

VC10は、がコピーコンストラクタを持っていると思われます。と思われます。したがって、タイプTrioの値をコピーするには、stringに変換しようとします。これは、あなたが提供するコンストラクタが受け入れるものです(他の引数にはデフォルト値を与えることができます)。これはあなたが得るエラーが文句です:

に 'constのトリオ' からパラメータ1を変換することはできません 'のconstのstd :: < _Elem、_Traits、_Ax> &のbasic_string'

をあなたは確認することができますこれは明示的にコピーコンストラクタを追加することで何が起こっているか確かであり、エラーが消えて見ていること:それはコピーコンストラクタを見ているので、

Trio(Trio const& t) { *this = t; } 

は今、VC10が満たされ、コードは罰金コンパイルします。

しかし、コピーコンストラクタがユーザーによって明示的に提供されていない場合、コンパイラは暗黙的にコンストラクタを生成する必要があります。 C++ 11標準のパラグラフ12.8/7あたり:クラス定義が明示的にコピーコンストラクタを宣言していない

場合は、1が暗黙的に宣言されています。クラス定義が移動コンストラクタまたは移動代入演算子を宣言する場合、暗黙的に宣言されたコピーコンストラクタは削除されたものとして定義されます。それ以外の場合は、デフォルト(8.4)として定義されます。 [...]

クラスTrioは、コピーコンストラクタを明示的に宣言しません。パラグラフ12による。C++ 11標準の8/2は、実際には:最初のパラメータは、タイプX &、CONST X &、揮発性X &である場合

クラスXのための非テンプレートコンストラクタは、コピーコンストラクタありますまたはconstの揮発性X &は、どちらか誰他のパラメータまたは他のすべてのパラメータがデフォルト引数したがって

(8.3.6)

がきていない、あなたが明示的に提供コンストラクタはないコピーコンストラクタとすべきですでは、コピーコンストラクタの暗黙的な生成を禁止していません。

VC10は、コピーコンストラクタとして提供するコンストラクタを誤って解釈している可能性があります。したがって、暗黙的にコンストラクタを生成しません。しかし、上記のように、この動作は正しくないので、バグとなります。(*)

補足として、コードはClang 3.2、GCC 4.7.2、ICC 13.0で正常にコンパイルされます。 1。

UPDATE:

私はstd::tuple<>を伴わない単純なデータ構造での問題を再現してみました、と私は失敗しました。したがって、このバグは、あなたのコンストラクタがVC10によって明示的なコピーコンストラクタとして誤解されているという事実によるものではありません。ただし、VC10の動作が正しくないという事実は変わりません。

+1

+1は完全性と標準への参照です。 – pstrjds

+0

それはうまくいった。私はTrioに明示的なコピーコンストラクタを追加しました。ありがとうございました!!! – Aaron

+0

@Aaron:喜んでそれは助けました:-) –

1

をいただき、ありがとうございます、これはVS2010でのちょうど問題であるように見えます。私はそれについて提出されたバグがあるかどうかを見ていませんでした。これはVS2012とgcc-4.7.2の両方でコンパイルします。

+0

ありがとうございます。 VS2010がTrio用のコピーコンストラクタを生成しないのはなぜか分かりませんが、明示的にコンパイルしないとコンパイルできません。 – Aaron

関連する問題