2014-01-10 76 views
0

在下面的簡化代碼,我嘗試這樣:上溯造型上的功能參數模板對象失敗

struct A{}; 
struct B : public A {}; 
void func(A &a) {} 
B b; 
func(b); 

通常,這是工作,但在下面的更復雜的代碼它不工作。 我想我錯過了模板上的東西。

爲什麼不可能從DenseVector<container_reference<std::array<double, 25ull>>>改爲container_reference<std::array<double, 25ull> >&?因爲你試圖綁定臨時container_referencerow返回在調用swap

#include <iostream> 
#include <vector> 
#include <array> 
#include <cassert> 

using namespace std; 


template<class C> 
struct container_reference 
{ 
    typedef typename C::iterator iterator; 
    container_reference(iterator f, iterator e) : f(f), e(e) {} 
    void swap(container_reference &c) { std::swap(*f, *(c.f)); /*...and more*/ } 
    iterator f,e; 
}; 

template<typename C> 
struct DenseVector : public C { using C::C; }; 

template<typename C> 
struct DenseMatrixRect 
{ 
    typedef DenseVector<container_reference<C>> row_vector; 
    row_vector row(unsigned int i) 
    { 
     auto it = container.begin() + i * width; 
     return row_vector(it, it + width); 
    } 
    C container; 
    unsigned int width; 
}; 


int main() 
{ 
    DenseMatrixRect<std::array<double, 25>> m; m.width = 5; 
    m.row(0).swap(m.row(1)); 
    return 0; 
} 
+0

_「沒有關係」 t work「_非常模糊。它怎麼不起作用?你有編譯器錯誤嗎?它會崩潰嗎?你有錯誤的價值嗎? –

+0

我完成了缺少的部分。無法將DenseVector :public C'轉換爲'C'。 – Chameleon

回答

3

你的代碼失敗。

你根本忘了綁定const引用和標記方法本身const

void swap(const container_reference &c) const { std::swap(*f, *(c.f)); /*...and more*/ } 
//  ^^^^^       ^^^^^ 

由於您只交換的c的(非const)內容,而不是它本身c,你不需要它是可修改的。雖然,值得指出的是,這是一個很不尋常的swap,其中兩個參數都是const,因爲它們只是交換真實內容的佔位符。

+0

因爲'operator [](....)const',所以最好是這樣的: 'void swap(container_reference && c)' 謝謝! – Chameleon

1

給它一個名稱,那麼它是一個左值和演員的工作原理:

auto x = m.row(1); 
m.row(0).swap(x); 

另一種選擇是添加一個版本交換是需要臨時對象:

void swap(container_reference &&c) { std::swap(*f, *(c.f)); /*...and more*/ }