2016-10-07 14 views
12

私はいくつかのstd::unordered_mapsを持っています。それらはすべてキーとしてstd::stringを持ち、そのデータは異なります。私はそのデータが有線を介して接続されたクライアントに送信される必要があるため、指定されたマップのキーからCSV文字列を作成したい。現時点では、それぞれのマップごとにメソッドがあります。私は、これは一般的な作りたかったと私は、次のを思い付いた:C++ 14メソッドの定義でautoキーワードを使用

std::string myClass::getCollection(auto& myMap) { 
    std::vector <std::string> tmpVec; 
    for (auto& elem : myMap) { 
     tmpVec.push_back(elem.first); 
    } 
    std::stringstream ss; 
    for (auto& elem : tmpVec) { 
     ss << elem <<','; 
    } 
    std::string result=ss.str(); 
    result.pop_back(); //remove the last ',' 
    return result; 
} 

私は日食を使用して、GCC 6.1.0と-std = C++ 14でコンパイルすると、それはコンパイルが、それはリンクされません。

Invalid arguments ' Candidates are: std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>> getCollection() '

がどのように私はこれを解決するのです: リンカは、それは常に私に語った、未定義std::__cxx11::getCollection(someMap);かかわらず、地図データの

を参照すると、私はそれを呼び出す方法について不平を言いますか?

+5

'std :: string myClass :: getCollection(auto&myMap)'は有効な構文ではありません。特に、 'auto'はメンバ関数にとって有効なパラメータ型ではありません。 – ildjarn

+0

は私が別のアプローチを使って可能なことを達成しようとしているのですか?私は、C++ 14のパラメータとしてautoを使うことは可能だと考えました...明らかに私は間違っています... – ZoOl007

+3

"*私はC++ 14のパラメータとしてautoを使用することが可能だと思いました... * "ラムダのみ。 "*私は別のアプローチを使って可能なことを達成しようとしていますか?* "はい、通常のテンプレートを使用してください:' template std :: string myClass :: getCollection(MapT&myMap) ' – ildjarn

答えて

15

C++ 14個のautoパラメータのみ(@のildjarnさんのコメントどおり)ラムダで許可されていると同じように、あなただけ例えば、マップタイプにtemplateized 関数テンプレートを、開発することができます:

#include <sstream> 
#include <string> 
#include <vector> 

class myClass { 
... 

template <typename MapType> 
std::string getCollection(const MapType& myMap) { 
    std::vector <std::string> tmpVec; 
    for (const auto& elem : myMap) { 
     tmpVec.push_back(elem.first); 
    } 
    std::stringstream ss; 
    for (const auto& elem : tmpVec) { 
     ss << elem <<','; 
    } 
    std::string result=ss.str(); 
    result.pop_back(); //remove the last ',' 
    return result; 
} 

const - 正解の場合にはconstの追加にも注意してください。

また、理由だけ(より多くのコード、バグのためのより多くの可能性、より多くのオーバーヘッドが、より少ない効率である)中間vector<string>を移入することなく、直接、文字列ストリームオブジェクトを使用して出力文字列を構築していませんか?

そして、あなたは出力ストリームとして文字列ストリームを使用することにだけ興味があるので、それをより効率的だともっと自分の意思を伝えるよう、ostringstream代わりのstringstreamを使用すると良いです。

#include <sstream> // for std::ostringstream 
#include <string> // for std::string 
... 

template <typename MapType> 
std::string getCollection(const MapType& myMap) { 
    std::ostringstream ss; 
    for (const auto& elem : myMap) { 
     ss << elem.first << ','; 
    } 
    std::string result = ss.str(); 
    result.pop_back(); // remove the last ',' 
    return result; 
} 
+0

ありがとうございました。私は同じリンクの問題を抱えています... 'std :: __ cxx11 :: – ZoOl007

+0

への未定義の参照はいくつかのヘッダにインラインで実装されていますか、あるいは少なくともあなたのクライアントのコードからアクセス可能ですか?必要なヘッダー(例: ''、 ''、 ''、マップコレクションのヘッダー)をすべて含めていますか? –

+0

はい、持っています\tテンプレート \t std :: string getCollection(MapType&myMap);テンプレート/関数があるcppに含まれるヘッダファイルにあり、クラスのメソッドが呼び出される別のヘッダにもインクルードされています。 – ZoOl007

7

なぜテンプレートを使用しないのですか?

template <typename TMap> 
std::string myClass::GetCollection(TMap &myMap) { 
    std::vector <std::string> tmpVec; 
    for (auto& elem : myMap) { 
     tmpVec.push_back(elem.first); 
    } 
    std::stringstream ss; 
    for (auto& elem : tmpVec) { 
     ss << elem <<','; 
    } 
    std::string result=ss.str(); 
    result.pop_back(); //remove the last ',' 
    return result; 
} 

あなたの方法はまったく同じですが、代わりにautoキーワードで、私たちは、型推論を処理するために、テンプレート関数の構文を使用します。

+3

関数にパラメータ型として 'auto'を使うことはできないと言われますか? – Rakete1111

+0

ありがとう、私はまだ定義されていないrefere nceを 'std :: __ cxx11 :: – ZoOl007

+0

@ ZoO007:これは名前空間なので、何かを最後から残しておく必要があります。この場合の重要な部分...] - ] – ildjarn

6

autoパラメータは、C++でonly allowed in lambdasです。

あなたのような古典的な関数では、lambdaはテンプレートではありませんが、関数テンプレート(基本的にはラムダの場合)が宣言されている可能性があります。

関連する問題