2

似たような質問に解決策がある場合、私は同様のエラー出力/問題を持つものを見つけることができませんでした。emplace_backへの完璧な転送テンプレートパラメータパック - コンパイルに失敗しました

私はこのコードをコンパイルしようとしています:それはとコンパイルに失敗しかし

#include <vector> 
using namespace std; 

template< typename value_type > 
class obj 
{ 
    vector<value_type> m_v; 
    public: 

    template<class... vaList_t> 
    void _emplace_back(vaList_t&&... i_values) 
    { 
     m_v.emplace_back(forward<vaList_t>(i_values)...); 
    } 
}; 

int main() 
{ 
    obj<int> thing; 
    thing._emplace_back(1,2,3,4); 
    return 0; 
} 

を:

In file included from /usr/include/x86_64-linux-gnu/c++/4.9/bits/c++allocator.h:33:0, 
       from /usr/include/c++/4.9/bits/allocator.h:46, 
       from /usr/include/c++/4.9/vector:61, 
       from 1: 
/usr/include/c++/4.9/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = int; _Args = {int, int, int, int}; _Tp = int]': 
/usr/include/c++/4.9/bits/alloc_traits.h:253:4: required from 'static std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = int; _Args = {int, int, int, int}; _Alloc = std::allocator<int>; std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> = void]' 
/usr/include/c++/4.9/bits/alloc_traits.h:399:57: required from 'static decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = int; _Args = {int, int, int, int}; _Alloc = std::allocator<int>; decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = <type error>]' 
/usr/include/c++/4.9/bits/vector.tcc:97:40: required from 'void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {int, int, int, int}; _Tp = int; _Alloc = std::allocator<int>]' 
13:3: required from 'void obj<value_type>::_emplace_back(vaList_t&& ...) [with vaList_t = {int, int, int, int}; value_type = int]' 
20:30: required from here 
/usr/include/c++/4.9/ext/new_allocator.h:120:4: error: new initializer expression list treated as compound expression [-fpermissive] 
    { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } 

質問:

  • は完璧転送するためのテンプレート、この構文的に正しいですパラメータパック? (そうでない場合は何ですか?)
  • この動作を達成する正しい方法は何ですか?

ありがとうございます。

ご迷惑をおかけして申し訳ありません。追加する複数の要素が含まれている完璧な転送し、テンプレートパラメータパックで

template< class... Args > void emplace_back(Args&&... args); 

:私はタイプの署名でemplace_backと呼ばれるこのベクトル関数を呼び出すしようとしています。

例:

  • "1,2,3,4" - 3種類のオブジェクトを追加 -
  • "真、偽、偽の" emplace_backを経由して、ベクターの背面に4つの異なるオブジェクトを追加emplace_back
+1

はおそらく、あなたが 'm_v.insert意味(m_v.end()、{前方(i_valuesを)...});'、または、 '(m_v.emplace_back (転送(i_values))、...); ' –

+1

ベクトルに4個のアイテムを挿入しますか? – kennytm

+0

@PiotrSkotnicki "、..."はコンパイルされません。インサートはコンパイルされます。しかし、それは完璧なパラメータパックを転送していないのですか? insertの関数引数はイテレータと初期化リストなので、オーバーヘッドが増えますか? – QuantumKarl

答えて

4

c.emplace_back介しベクターの背面には、c単一要素を作成します。複数のものが必要な場合は、emplace_backを展開の一部にする必要があります。このような何か:

template<class... vaList_t> 
void _emplace_back(vaList_t&&... i_values) 
{ 
    int dummy[] = { 0, (m_v.emplace_back(forward<vaList_t>(i_values)), 0)... }; 
} 

[Live example]

+0

ありがとうございます。私は今すぐ見る: "新しい要素をコンテナの最後に追加する。" (テンプレートパラメータバージョンは、複数の引数を持つオブジェクト用です。複数のオブジェクトに注意してください)。 – QuantumKarl

+0

@QuantumKarlまさに。 'push_back'を介した' emplace_back'の本当の力は、コンストラクタの引数を一貫して渡すことによって、コンテナ内に要素を直接(コンテナ内でコピー/移動するのではなく)構築することができるということです。 – Angew

関連する問題