2016-12-29 4 views
0

理由がありますstd::make_tupleはリスト初期化オブジェクトのパラメータを受け入れませんか?リスト初期化オブジェクトをstd :: make_tupleに渡す

#include <string> 
#include <map> 
#include <cstdint> 

class FileInfo 
{ 
public: 
    FileInfo() = default; 
    FileInfo(const std::string &name, uint64_t size) : mName(name), mSize(size) { } 

    bool operator == (const FileInfo& other) const 
    { 
     return mName == other.mName; 
    } 

private: 
    std::string mName; 
    uint64_t mSize = 0; 
}; 

void function(FileInfo fileInfo) { } 

using Modifications = std::map<std::string, std::tuple<std::string, FileInfo, FileInfo>>; 

int main(int argc, char *argv[]) 
{ 
    Modifications modifications{ 
     { "f1", std::make_tuple("changed", FileInfo{ "f1", 1 }, FileInfo{ "f1", 2 }) }, 
     { "f2", std::make_tuple("removed", FileInfo{ "f2", 1 }, FileInfo{}) }, 
     { "f3", std::make_tuple("added", FileInfo{}, { "f3", 2 }) } // Error 
    }; 

    function({ "f3", 2 }); // OK 

    return 0; 
} 

マップから三番目のペアは、次のエラーを与える:

Error C2660 'std::make_tuple': function does not take 3 arguments

このエラーは私には意味がありません。 の型を明示的にstd::map<std::string, std::tuple<std::string, FileInfo, FileInfo>>と宣言したとき、第3パラメータを受け入れるのはなぜですか?std::make_tupleコンパイラの制限がありますか、これは単に標準から省略されていますか?

注:この質問は、ブレースリストからタプルを構築するとは関係ありません:initialize-an-stdarray-of-tuples-with-curly-braces

+2

問題は、あなたが 'の前から' FileInfo'を省略することである{ "F3"、2" } ' –

+0

' Modifications'は無関係である、 'make_tuple(BLA、BLA、BLA)'であるのタイプ式の結果を処理するために何をするのかとは無関係に評価される式(C++のすべての式と同じ) –

+0

実際に最初の2つのエントリを例として挙げました。要点は、{{}}と{FileInfo {} 'の両方で動作することが期待されています。 –

答えて

2

としては、エラーがあなたがmake_tuple関数への呼び出しでFileInfoオブジェクトを構築していないという事実にあるコメントで指摘、C++コンパイラでは、3番目のオブジェクトをどのようにしたいかを知る方法がありません。あなたはこの

std::make_tuple<std::string, FileInfo, FileInfo>("added", FileInfo{}, { "f3", 2 }) 

のようなものへの呼び出しを変更した場合はその後も、コードは動作しますが、あなたは、引数リストで物事の種類を推定することができるようにmake_tuple機能を必要としています。

The compiler cannot deduce the type of an initializer list in a template argument

関連する問題