bugfix> c++ > 投稿

ここでコードがコンパイルされない理由を理解できません。次の行に沿って、標準ライブラリから多くのエラーメッセージが表示されます。

main3.cpp:10:20:   required from ‘void addAndCout(T&&) [with T = const char (&)[11]]’
main3.cpp:20:28:   required from here
/usr/include/c++/5/bits/alloc_traits.h:450:27: error: forming pointer to reference type ‘const char (&)[11]’
       using pointer = _Tp*;
                           ^
/usr/include/c++/5/bits/alloc_traits.h:453:39: error: forming pointer to reference type ‘const char (&)[11]’
       using const_pointer = const _Tp*;

Tが推論されていないときにT&&は普遍的な参照であり、右辺値または左辺値にバインドできるはずだと思ったので、これは意味がありません。投稿されたこの例は、Scott Meyerの「Effective Modern C ++」のセクションをコピーしようとしているところです。本の例の写真

なぜこれがコンパイルされないのか、ここで何が欠けているのか不思議に思っています。なぜなら、それは事実上、例と同じであると言えるからです。

#include <iostream>
#include <vector>
#include <string>
using std::cout;
using std::endl;
template<typename T>
void addAndCout(T &&name)
{
    std::vector<T> v;
    cout << name << endl;
    v.emplace_back(std::forward<T>(name));
}
int main(int argc, char **argv)
{
    std::string name {"test"};
    addAndCout(std::string("rvalue")); // FINE      move rvalue instead of copying it
    addAndCout("New string");          // ERROR     make a new string instead of copying
    addAndCout(name);                  // ERROR     copy lvalue
}

回答 2 件
  • vector は存在できません  参照、またはCスタイルの配列のベクトル。行 std::vector<T> v;  引数が左辺値および/またはCスタイルの配列の場合、コンパイルに失敗します。

    あなたのコードは、あなたが std::vector<T> v; をするという点で本と異なります  本はそうではありませんが。

    使用法 addAndCout(name); をサポートするには  ベクトル定義を次のように変更できます。

    std::vector< typename std::remove_cv<typename std::remove_reference<T>::type>::type > v;
    
    

    remove_cv  constオブジェクトのベクトルも存在できないためです)。

    Cスタイルの配列をサポートするには、追加のオーバーロードを追加するのが最も簡単です。

    template<typename T, size_t N>
    void addAndCout(T (&name)[N])
    {
         // do whatever...
    }
    
    

  • addAndCout(std::string("rvalue")); を行うとき  これは右辺値です 参照およびテンプレートパラメータTはstd :: stringおよび this::std::vector<std::string> v;  有効です。

    しかし、あなたが addAndCout("New string"); をするとき  Tはconst charの配列への参照として推定され、参照のベクトルを持つことはできません

    そして、あなたが addAndCout(name); をするとき  l値のrefを渡している、および Tは std::string& になります  同様の参照のベクトルを持つことはできません。

あなたの答え