2012-01-22 186 views
0

我想弄清楚如何將typecast運算符添加到以下嵌套類以允許主要編譯,但我無法確定需要什麼。main中最後一個賦值的下一個引起問題。請注意,最後一個分配使用類型轉換來使其工作。我懷疑我需要爲'add'類定義一個類型轉換運算符,但是如何?嵌套的模板類型鑄造

對不起長列表,但這很簡單,因爲我知道如何做到這一點。

#include <iostream> 
using namespace std; 

template <char I> struct index { }; 

template <char I, char J> struct marker; 

// simple class with just a 2 element int array 
struct A { 
    A() { } 
    A(int i, int j) { a[0] = i; a[1] = j; } 
    A(const A& x) { a[0] = x(0); a[1] = x(1); } 

    template<char I, char J> 
    marker<I,J> operator()(const index<I>&, const index<J>&) { 
    return marker<I,J>(*this); 
    } 

    friend std::ostream& operator<<(std::ostream& os, const A& _A) { 
    return os << '{' << _A.a[0] << ',' << _A.a[1] << '}'; 
    } 

    int& operator()(int i) { return a[i]; } 
    const int& operator()(int i) const { return a[i]; } 

private: 
    int a[2]; 
}; 

template <char I, char J> 
struct marker { 
    const int DI; 
    const int DJ; 

    marker(A& a) : _A(a), DI(1), DJ(0) { } 
    marker(A& a, const int i, const int j) : _A(a), DI(i), DJ(j) { } 
    marker(const marker& m) : _A(m._A), DI(m.DI), DJ(m.DJ) { } 

    // cast I,J => J,I 
    operator marker<J,I>() const { 
    return marker<J,I>(_A, DJ, DI); 
    } 

    marker& operator=(const marker& m) { 
    _A(0) = m(0); 
    _A(1) = m(1); 
    return *this; 
    } 

    // returns the i'th or (1-i)'th element of _A 
    int operator()(int i) const { 
    return _A(i*DI + (1-i)*DJ); 
    } 

    template<class LHS, class RHS> 
    struct add { 
    const LHS& lhs; 
    const RHS& rhs; 

    add(const LHS& l, const RHS& r) : lhs(l), rhs(r) { } 

    int operator()(int i) const { 
     return lhs(i) + rhs(i); 
    } 

    add< add,marker > operator+(const marker& b) { 
     return add< add,marker >(*this, b); 
    } 
    }; 

    add< marker,marker > operator+(const marker& b) const { 
    return add< marker,marker >(*this,b); 
    } 

    template<class LHS> 
    void operator=(const add<LHS,marker>& expr) { 
    _A(0) = expr(0); 
    _A(1) = expr(1); 
    } 

private: 
    A& _A; 
}; 


int main() { 
    index<'i'> i; 
    index<'j'> j; 
    A a(1,2), b; 

    b(i,j) = a(j,i); 
    cout << b << endl; // "{2,1}" 

    b(i,j) = a(i,j) + a(j,i); 
    cout << b << endl; // "{3,3}" 

    b(i,j) = a(j,i) + a(i,j); // fails to compile 
    cout << b << endl; // should be "3,3" 

    b(i,j) = (marker<'i','j'>)a(j,i) + a(i,j); // works fine 
    cout << b << endl; // "{3,3}" 

    return 0; 
} 
+2

這可能不是您的問題的原因,但以下劃線和大寫字母(如'_A')開頭的標識符[保留在任何範圍內](http://stackoverflow.com/a/228797/185171 ) –

+0

謝謝。不知道。儘管在這種情況下沒有編譯器的抱怨。 – gogators

回答

0

[已解決]好的,算出來了。我所要做的就是下面的成員添加到類標記:

template <class LHS> 
    void operator=(const typename marker<J,I>::template add< LHS, marker<J,I> >& expr) { 
    myA(0) = expr(1); 
    myA(1) = expr(0); 
    } 

參數規範的語法是什麼搞亂了我。 servn的給我提供了線索,一些試驗和錯誤得到了正確的語法。

1

鐺提供了以下錯誤:

/tmp/webcompile/_13759_1.cc:97:10: error: no viable overloaded '=' 
    b(i,j) = a(j,i) + a(i,j); // fails to compile 
    ~~~~~~^~~~~~~~~~~~~~~~ 
/tmp/webcompile/_13759_1.cc:44:11: note: candidate function not viable: no known conversion from 'add<marker<'j', 'i'>, marker<'j', 'i'> >' to 'const marker<'i', 'j'>' for 1st argument; 
    marker& operator=(const marker& m) { 
     ^
/tmp/webcompile/_13759_1.cc:76:8: note: candidate template ignored: failed template argument deduction 
    void operator=(const add<LHS,marker>& expr) { 
    ^

錯誤只是意味着編譯器無法找到執行問題的分配方式。編譯器然後列出它試過的兩個operator=。第一個顯然不匹配。對於第二個,failed template argument deduction只是意味着編譯器無法知道如何將參數轉換爲任何類型LHSconst add<LHS,marker>&。也許你想要以下?

template<class LHS, class RHS> 
void operator=(const add<LHS,RHS>& expr) 

編輯: 如果顯式調用運算符=和強制模板參數,這個問題變得更加明顯:

/tmp/webcompile/_28787_0.cc:95:10: error: no matching member function for call to 'operator=' 
    b(i,j).operator=<marker<'j', 'i'>, marker<'j', 'i'> >(a(j,i) + a(i,j)); // fails to compile 
    ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
/tmp/webcompile/_28787_0.cc:76:6: note: candidate function [with LHS = marker<'j', 'i'>, RHS = marker<'j', 'i'>] not viable: no known conversion from 'add<marker<'j', 'i'>, marker<'j', 'i'> >' (aka 'marker<'j', 'i'>::add<marker<'j', 'i'>, marker<'j', 'i'> >') to 'add<marker<'j', 'i'>, marker<'j', 'i'> >' (aka 'marker<'i', 'j'>::add<marker<'j', 'i'>, marker<'j', 'i'> >') for 1st argument; 
void operator=(add<LHS,RHS>); 
    ^

具體參數爲marker<'i', 'j'>::add,並且參數爲marker<'j', 'i'>::add

+0

認爲這是類似的東西。你的建議雖然更一般,但也給出了類似的錯誤。 – gogators

+0

另外,如果您在給出錯誤的行上將'b(i,j)'更改爲'b(j,i)',則參數將變爲'marker <'j', 'i'> :: add'並且代碼將被編譯。但是,我想知道解決方案是什麼。 –