2011-06-18 32 views
2

請考慮下面的代碼:從模板參數推導並調用它的拷貝構造函數

template<class basic_ios_type> 
class basic_ios_adaptor; 

template<template<typename, class> class basic_ios_type, typename char_type, class traits_type> 
class basic_ios_adaptor<basic_ios_type<char_type, traits_type>> 
    : public basic_ios_type<char_type, traits_type> 
{ 
public: 
    typedef basic_ios_type<char_type, traits_type> base_type; 

    basic_ios_adaptor(base_type const& other) 
     : base_type(other) 
    { 
    } 
}; 

唯一可用的構造是一個拷貝構造函數,這需要常量引用的基本類型。 實例:

std::ofstream     x(std::ofstream("")); // ok 
basic_ios_adaptor<std::ofstream> y(std::ofstream("")); // error 

的Visual C++:

'的std :: basic_ios < _Elem,_Traits> :: basic_ios' :不能訪問類 「的std :: basic_ios聲明爲專用構件 < _Elem,_Traits>」

英特爾:

沒有構造 的實例 「的std :: basic_ofstream < _Elem, _Traits> :: basic_ofstream [與_Elem =炭,_Traits =標準:: char_traits]」 匹配參數列表

任何人可以解釋對我來說爲什麼這不起作用?

+0

複製流是什麼意思?流不是容器,而是數據流。 –

+1

@Yochai Timmer - 這不是你的代碼,它不是你的編碼標準。 –

+0

@Yochai:不,不要用大寫開頭。命名一個以大寫開頭的C++標準類型。 –

回答

4

您不能複製流,因爲它們的拷貝構造函數是私有的(或更具體地說,來自basic_ios的拷貝文件)。請參閱this question

4

STL流不能複製構建,這就是你的問題。

+0

爲什麼它爲std :: ofstream工作? ('std :: ofstream x(std :: ofstream(「」))') – 0xbadf00d

+0

@ FrEEzE2046:不是。你不會複製。看到我對你的問題的評論。 –

0

好吧,我想實現的是創建任何basic_ios類我從中派生的可能性。所以,在我的例子中,我只是想爲指定的文件創建一個ofstream。

有可能以下列方式:

template<template<typename, class> class basic_ios_type, typename char_type, class traits_type> 
class basic_ios_adaptor<basic_ios_type<char_type, traits_type>> 
    : public basic_ios_type<char_type, traits_type> 
{ 
public: 
    typedef basic_ios_type<char_type, traits_type> base_type; 

    template<class create> 
    basic_ios_adaptor(create& create) 
    { 
     create(static_cast<base_type*>(this)); 
    } 
}; 

應該SAFTE的指針傳遞給基類,因爲在這個階段,它已經分配和建造。

用法:

struct construct 
{ 
    void operator()(std::ofstream* o) { 
     *o = std::ofstream("file"); 
    } 
}; 

construct c; 
basic_ios_adaptor<std::ofstream> y(c); 

任何其他解決辦法?

+0

這是一個答案或問題? –

+0

這是一個答案,因爲它似乎工作。但是這取決於編譯器,如果他忽略它(請參閱我的初始文章中的評論)。 – 0xbadf00d

+0

儘管我對有關elision的評論是錯誤的,但流仍然無法複製。我認爲你在這裏做的是_moving_,這對於C++ 0x來說是新的。只要你意識到這一點,只要你的代碼知道它,你可能會好起來的...... –

1

如前所述,標準流不可複製。但是,在C++ 0x中,它們是可移動的。根據你使用的編譯器/設置,這可能是你看到的行爲。 ofstream x(std::ofstream("x"));創建臨時文件ofstream,然後將該臨時文件移動到名爲ofstream中。這是完全合法的。但是,在您的代碼中,您定義了一個複製構造函數,因此不會發生任何移動。副本仍然被禁止,所以編譯器會阻止你。

因此,對於您的班級,您還必須移動,而不是複製。 ios_base_adaptor(base_type&& other) : ofstream(std::move(other)) { }

+0

這似乎也很有可能,好點。 – Xeo