簡體   English   中英

C ++ 0x:切片模板無法使用基於范圍的for()進行編譯

[英]C++0x: Slice template fails to compile with range-based for()

當嘗試使Slice模板類與基於范圍的for()一起使用時,在gcc 4.6.1中出現以下編譯錯誤(使用auto在for()行上發生):

  1. 我知道boost中有一個slice類-這只是出於說明目的
  2. 我設法使基於范圍的for()在普通類上正常工作-只是模板類有問題。

我究竟做錯了什么?

sandbox.cpp:31:17:錯誤:無法轉換'(& t)->Slice<T>::Begin [with T = int, typename std::vector<_RealType>::const_iterator = __gnu_cxx::__normal_iterator<const int*, std::vector<int> >]()''const const_iterator {aka const __gnu_cxx::__normal_iterator<const int*, std::vector<int> >}''std::vector<Slice<int>, std::allocator<Slice<int> > >::const_iterator {aka __gnu_cxx::__normal_iterator<const Slice<int>*, std::vector<Slice<int>, std::allocator<Slice<int> > > >}'

sandbox.cpp:在函數'typename std::vector<_RealType>::const_iterator end(const T&) [with T = Slice<int>, typename std::vector<_RealType>::const_iterator = __gnu_cxx::__normal_iterator<const Slice<int>*, std::vector<Slice<int>, std::allocator<Slice<int> > > >]'

碼:

#include <vector>
#include <algorithm>

using namespace std;

template< typename T >
class Slice 
{
public:
    Slice( const vector< T >& v,
        typename vector< T >::const_iterator it0, 
        typename vector< T >::const_iterator itEnd ) :
        m_v( v ), m_it0( it0 ), m_itEnd( itEnd )
    { }

public:
    const typename vector<T>::const_iterator Begin() const
        { return m_it0;     }
    const typename vector<T>::const_iterator End()   const
        { return m_itEnd; }

private:
    const vector< T >&                         m_v;
    const typename vector< T >::const_iterator m_it0, m_itEnd;
};

template< typename T >
typename vector<T>::const_iterator
begin( const T& t )
{
    return t.Begin();
}

template< typename T >
typename vector<T>::const_iterator
end( const T& t )
{
    return t.End();
}

int main(int argc, char** argv)
{
    vector<int> v = { 1, 2, 3, 4, 5, 6 };
    Slice<int>  s( v, v.begin()++, v.end() );
    for( auto x : s ) 
    {

    }
    return 0;
}

您的beginend模板參數設置錯誤。 它們被傳遞給s ,即Slice<int> ,因此T被推導為Slice<int> 然后,返回類型為vector<Slice<int> >::const_iterator 但是Slice<int>::Begin返回vector<int>::const_iterator

正如您在評論中提到的那樣,解決方案是將參數從const T&更改為const Slice<T>& 這樣, T被推導為int而不是Slice<int> ,並且返回類型像您想要的那樣成為vector<int>::const_iterator

template<typename T>
typename std::vector<T>::const_iterator
begin(const Slice<T>& s) {
  return s.Begin();
}

但是,如果你改變你的函數名稱begin ,而不是Begin ,你可以使用std::begin ,它有一個更通用的行為:

template<typename T>
auto begin(const T& t) 
-> decltype(t.begin()) {
  return t.begin();
}

基於范圍的for語句具有一個特殊的規則,該規則確保即使您的類型不是名稱空間std的一部分,也可以通過依賴於參數的查找來找到std::begin 減少您的工作量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM