2

std::remove_reference を試しています。たとえば、要素の型を配列から抽出することはできますが、remove_reference を STL コンテナーで動作させるにはどうすればよいでしょうか? たとえば、次の remove_reference を使用して、ベクターの要素にイテレータを返したいとします。

#include <iostream>
#include <vector>
#include <type_traits>
using std::vector;
using std::cout;
using std::endl;
using std::begin;
using std::end;
using std::remove_reference;

template<typename T> 
auto my_end(T& c) -> typename remove_reference<decltype(&c[0])>::type
{
    return end(c)-1; //compile error when myend<vector> is instantiated
}

int main()
{
    int ia[] = {1,2,3,4,5,6,7,8,10};
    vector<int> v(begin(ia), end(ia));

    auto my_back1 = *my_end(ia);
    cout << my_back1 << endl; //prints 10

    auto my_back2 = *my_end(v);
    cout << my_back2 << endl; //should print 10
}

my_end<vector>がインスタンス化されたときのコンパイラ エラーは次のとおりです。

cannot convert from 'std::_Vector_iterator<_Myvec>' to 'int *'  
4

3 に答える 3

6

によって返されるタイプは何std::vector<T>::operator[]ですか?ですT&。したがって、の結果はdecltype(&c[0])ですT*

しかし、タイプはend(c)-1何ですか?イテレータです。

イテレータを返す場合は、decltype(end(c))または同様のものを使用します。


最後の要素への参照だけが必要な場合は、次を使用(またはラップ)できることに注意してください。

ia.back();

(何らかの理由で)イテレータが必要な場合でも、方向は気にしないでください:

ia.rbegin();

これにより、最後のエントリへの参照も解除されます。

コンテナが空の場合も安全ではありませmy_endん...しかし、もちろん、どのように使用する予定かはわかりません。

于 2012-10-29T15:33:42.367 に答える
4

remove_referenceここの目的は何ですか?std::vector<T>::end()イテレータを&c[0]生成しますが、要素へのポインタを生成します。

あなたが返すことを期待my_end()しているものを定義してください、そうすれば私たちはあなたが問題を解決するのを手伝うことができます。

イテレータを返すだけの場合は、次のように宣言します。

auto my_end(T& c) -> decltype(begin(c)) { }

しかし、もう一度、実験したいと思いますよremove_referenceね...?

于 2012-10-29T15:32:35.807 に答える
0

助けてくれてありがとう。以下の私のコメントでは、コードがインラインで不十分に見えるので、ここにもう一度示します。この時間remove_referenceは、たとえばイテレータを渡す必要がある場合に、戻り値の型を推測するのに役立ちます。(わかりましたので、それほど便利ではありません....)

#include <iostream>
#include <vector>
#include <type_traits>
using std::vector;
using std::cout;
using std::endl;
using std::begin;
using std::end;
using std::remove_reference;

template<typename T> 
auto my_end(T It) -> typename remove_reference<decltype(It)>::type
{
    return It-1; 
}

int main()
{
    int ia[] = {1,2,3,4,5,6,7,8,10};
    vector<int> v(begin(ia), end(ia));

    auto my_back1 = my_end(end(ia));
    cout << *my_back1 << endl; //prints 10

    auto my_back2 = my_end(end(v));
    cout << *my_back2 << endl; //should print 10
}
于 2012-10-29T18:28:35.627 に答える