2013-05-03 41 views
1

我有一個派生basic_ostream類和一個內聯修飾符(類似於setw)。我的流類也應繼承其父級的所有運算符< <行爲。我取決於我是否使用「使用」關鍵字或者沒有得到不同的編譯器錯誤:派生basic_ostream:「使用」關鍵字和運算符模糊過載<<

#include <iostream> 

struct modifier { }; 

template <typename C, typename T=std::char_traits<C> > 
struct mystream : public std::basic_ostream<C, T> 
{ 
    // this is where the trouble is 
    using std::basic_ostream<C, T>::operator <<; 

    inline mystream & operator << (const modifier & mod) 
    { 
     // ...custom behavior... 
     return *this; 
    } 
}; 

int main() 
{ 
    mystream<char> foo; 
    modifier m; 
    foo << "string"; // this fails if the using is present 
    foo << 123;  // this fails if the using is absent 
    foo << m; 
} 

當我把using指令中,編譯器是混淆了「串」輸出,如果我註釋掉,它會對整數123輸出感到困惑,在這兩種情況下,都會給我「錯誤:'運算符'<'<''的模糊超載。我有g ++ 4.2.1和g ++ 4.8的問題。這裏前進的方向是什麼?

+0

你爲什麼從'basic_ostream'派生?你在做什麼,非會員'運營商''不能做? – 2013-05-03 16:15:50

+0

我在下面評論 - 我的流有很多自定義行爲,包括它自己的streambuf等,並且該運算符需要更改流的狀態。 – 2013-05-03 16:22:02

+0

使用'xalloc'和'iword' /'pword',它們專門用於維護自定義流狀態。如果你想用你自己的'streambuf'('fstream'就是這麼做)來構建一些東西,你就可以從'basic_ostream'派生出來,只是不要添加任何'operator <<'成員給它。 – 2013-05-03 16:29:15

回答

3

而是然後從性病:: basic_ostream繼承,那會不會足夠只使用常規流重新實現< <爲您修改結構:

std::ostream & operator << (std::ostream &stream, const modifier & mod) 
{ 
    // ...custom behavior... 
    return stream; 
} 

你的解決方案似乎過於複雜,但我認爲你得到的實際錯誤來自你的超負荷< < - 它必須接受兩個參數(第一個參數是參考流本身)。

+0

我的流有很多自定義行爲,包括其自己的streambuf等。該運算符需要訪問我的流以更改其狀態。您是否建議將運營商遷移到全球範圍並讓它的朋友訪問該流?這是否解決了其他問題? – 2013-05-03 16:17:36

+0

好,然後直接mystream與運營商<<(const修飾及MOD)是行不通的,你需要在線mystream與運營商<<(mystream&流,const修飾及MOD),也不要在這個指針在函數內部操作但在流上作爲參數傳遞 - 因爲operator <<需要接受兩個參數來鏈接<< operators。試試看看是否會有其他錯誤。 – 2013-05-03 16:23:06

+0

是的,它必須在全局範圍內,如果你需要訪問私人成員,就給它的朋友訪問 - 它不能成爲成員操作員接受單一的論點,因爲那樣的事情,如foo <<「test」<< 123;將無法工作... – 2013-05-03 16:26:18

2

沒有using,這是明確的:編譯器將找不到<<成員重載任何 ,因爲你的函數隱藏 他們。 <<是會員,所以沒有using,它 消失。 <<不是會員,所以它仍然有效。

當您添加using:所有成員重載的是 可見,彷彿他們是你的類的成員。並且 "string"將被轉換爲char const*。超載 編譯器正試圖解決的是:

operator<<(mystream<char>, char const*). 

現在考慮一些重載的考慮:

std::ostream& mystream::operator<<(void const*); 
std::ostream& mystream::operator<<(bool); 
std::ostream& operator<<(std::ostream&, char const*); 

對於第一個參數(foo,一mystream),前兩個 函數都比第三個匹配更好(因爲它們是完全匹配的 );對於第二個參數(字符串文字),第三個函數是更好的匹配。因此:模棱兩可。

更一般地說,你的代碼有幾個問題。 基本上,你做不是<<經營者通過派生。由於您看到 ,它不起作用。也許更顯著,東西 這樣的:

foo << 123 << m; 

將無法​​正常工作,因爲foo << 123返回一個std::ostream&, 不是mystream,有沒有<<這將有 std::ostream&modifier工作。您可以通過添加 運營商<<定義新的免費功能:

std::ostream& 
operator<<(std::ostream& dest, modifier const& other) 
{ 
    // ... 
    return *this; 
} 

如果需要其他的數據格式,可以使用xallociwordpword得到它,例如定義一個機械手:

static int Modifier::modIndex = std::ostream::xalloc(); 

class mod1 
{ 
    int myModifier; 
public: 
    mod1(int m) : myModifier(m) {} 
    friend std::ostream& operator<<(std::ostream& dest, 
            mod1 const& mod) 
    { 
     dest.iword(modIndex) = myModifier; 
     return *this; 
    } 
}; 

然後,您可以訪問dest.iword(modIndex)得到這個信息 輸出程序。

iword()返回long&,對於您的 流的每個實例(以及您使用的每個不同索引)都會有所不同。

如果您需要了解更多信息,您可以使用pword代替 iwordpword返回到void*參考。如果您想 用它來指向動態分配的內存,不 忘記註冊一個回調來刪除它(使用 ios_base::register_callback)。

相關問題