2016-06-27 12 views
0

pair<char, int>というベクトルをSTLを使って1行に初期化したいと考えています。 私は以下の作品が見つかりましたが、同じ値を持つすべての要素の初期化しかできません。ペアの値を1行でインクリメントしながらペアのベクトルを初期化する方法C++

vector<pair<char, int>> myVec (26, std::make_pair('a', -1)); 

char型の要素のような増分になりますように、多分ラムダ関数か何かで、それを初期化する方法があります:古典を使用せずに1行で

(a,-1) (b,-1) (c,-1) etc... 

とこのすべてが初期化後にループしますか? ありがとうございます。

+1

'のstd :: vector'コンストラクタはこれをサポートしていない、'のstd ::イオタのようなものを使用' –

+0

この質問を見てください:http://stackoverflow.com/q/12511711/5513245 と特に最初の2つの答え。彼らはおそらくあなたがしたいことを達成するのを助けることができます! – Jonathan

+0

定型文やかなり複雑なラムダはありません。 –

答えて

5

これは不可能です(:

std::vector<std::pair<char, int>> vec { BOOST_PP_ENUM(26, PAIR, ~) }; 

は、このように展開ライナー)を使用せずにstd::generateを使用してternal依存(例えばブースト、他の回答を参照してください)

2ライナー:

std::vector<std::pair<char, int>> v(26); 
std::generate(v.begin(), v.end(), [] { static char c = 'a'; return std::make_pair(c++, -1);}); 
1

std::generateまたはstd::generate_nを使用することもできます。

または手書きの範囲ベースforループ—私は個人的にこの方法をお勧めします。


それともとしてBOOST_PP_ENUMを使用することができますライン

#include <iostream> 
#include <boost/preprocessor/repetition/enum.hpp> 

#define PAIR(count, i, data) std::make_pair('a' + i, -1) 

int main() 
{ 
    std::vector<std::pair<char, int>> vec { BOOST_PP_ENUM(26, PAIR, ~) }; 
} 

:ワンとして

std::vector<std::pair<char, int>> vec { 
     std::make_pair('a' + 0, -1), 
     std::make_pair('a' + 1, -1), 
     std::make_pair('a' + 2, -1), 
     . 
     . 
     std::make_pair('a' + 25, -1) 
}; 
+0

私たちがいくつかのマクロ定型句を設定しようとすれば、なぜいくつかのコード定型句はありませんか? –

+0

私は手書きの*範囲ベース* 'for'ループを個人的に好みます。 – Nawaz

+0

私はこの提案が気に入らないと思います。マクロは一般にコードを書くよりも安全性が低くなります。また、OPはSTLに依存するものを探しているように見え、参照を高めることで依存関係が追加されます。私たちはOPの依存関係を知りませんが、これを行うには過度の連携が必要です。ループを使用するほうが適切だったでしょう、IMHO。 – ray

0

あなたはそれをカットどのように、あなたはどのような「ベクトル生成の概念を定義する必要があるとしています" 手段。

最後に、これを表現する最もクリーンな方法は、関数内でベクトル生成をカプセル化し、RVOを使用して「正しいことを行う」ことです。

デバッグ時にブレークポイントを配置できることがわかります。

#include <vector> 
#include <utility> 

using namespace std; 

// define the concept of 'a generated vector'. 
// I used a lambda but this could just as well be a free function 
// or a function object 
auto generate_vec = [] (std::size_t n, char first_char) { 
    vector<pair<char, int>> myVec; 
    myVec.reserve(n); 
    while (n--) { 
    myVec.emplace_back(first_char++, -1); 
    } 
    return myVec; 
}; 

int main() 
{ 
    // use the concept here 
    vector<pair<char, int>> myVec = generate_vec(26, 'a'); 
} 
-1

あなたはこのようなものにすることができます。

class SomeClass 
{ 
public: 
    static char currentChar; 
    SomeClass() 
    { 
     intValue = -1; 
     charValue = currentChar; 
     currentChar = static_cast<char>(currentChar + 1); 
    } 
    char charValue; 
    int intValue; 
}; 
char SomeClass::currentChar = *"a"; 

をし、このようなベクターを作成します。それは最初から最後まで、26個の要素を作成し、各デフォルトコンストラクタます

std::vector<SomeClass> v(26); 

を意志文字を1つ増やす

+0

OPは、理想的には1つのライナーで簡単な解決策を求めました。代わりに完全なクラスを思いついた。私はこれが要求されているものからあまりにも離れていると思っていますし、他の意味合いが不当です。例えば、このクラスは実際にオブジェクトを表現するものではなく、単純に関数の仕事をしようとしています... ctorでは...正当な理由がないために名前空間を汚染し、より多くのリソースを使用します。悪いコード。 – ray

2

これは1行ではありませんが、ここでは一度書かれたいくつかのテンプレートオーバーヘッドで

vector<pair<char,int>> v; 
generate_n(
    back_insert_iterator<std::vector<pair<char,int>>>(v) 
, 26 
, [c = 'a']() mutable { return make_pair(c++, -1); } 
); 

Demo.

+0

私は、C++ 14で '[c = 'a'](){....}'がうまくいくかどうか疑問に思っていますか? – Nawaz

+0

@Nawaz残念なことに、いいえ、[cは読み取り専用とみなされるため] – dasblinkenlight

+0

うわー、['mutable'が助けになります](http://ideone.com/ZQBv57)。 – Nawaz

0

:ループなし

#include <utility> 

// Make Sequence 
// ============= 

namespace Detail { 
    template <typename ResultSequence, typename IntegerSequence> 
    struct make_sequence; 

    template <typename ResultSequence, typename IndexType, IndexType...Indices> 
    struct make_sequence<ResultSequence, std::integer_sequence<IndexType, Indices...>> 
    { 
     template <typename Callable, typename...Args> 
     static constexpr ResultSequence apply(Callable&& fn, Args&&...args) 
     { 
      return { fn(Indices, std::forward<Args>(args)...) ... }; 
     } 
    }; 
} // namespace Detail 

template <typename ResultSequence, std::size_t N, typename Callable, typename...Args> 
constexpr ResultSequence make_sequence(Callable&& fn, Args&&...args) 
{ 
    return Detail::make_sequence<ResultSequence, std::make_index_sequence<N>>::apply(fn, args...); 
} 

// Test 
// ==== 

#include <array> 
#include <iostream> 
#include <vector> 
#include <map> 
int main() { 
    struct MissingConstexprLambda 
    { 
     constexpr std::pair<char, int> operator() (std::size_t i) { 
      return std::make_pair(char('a' + i), -1); 
     }; 
    }; 

    std::cout << "Array:\n"; 
    constexpr auto a = make_sequence<std::array<std::pair<char, int>, 3>, 3>(MissingConstexprLambda()); 
    for(const auto& p : a) 
     std::cout << p.first << " = " << p.second << '\n'; 
    static_assert(std::get<1>(a).first == 'b', ""); 

    auto lambda = [](std::size_t i) { return std::make_pair('a' + i, -1); }; 

    std::cout << "Vector:\n"; 
    auto v = make_sequence<std::vector<std::pair<char, int>>, 3>(lambda); 
    for(const auto& p : v) 
     std::cout << p.first << " = " << p.second << '\n'; 

    std::cout << "Map:\n"; 
    auto m = make_sequence<std::map<char, int>, 3>(lambda); 
    for(const auto& p : m) 
     std::cout << p.first << " = " << p.second << '\n'; 
} 
+0

は過剰殺人のように思う – Xiobiq

+0

@Polikdir少し冗長で一度使うことはないが、過剰殺しはしない –

関連する問題