从模板参数派生并调用其复制构造函数

时间:2011-06-18 16:06:13

标签: c++ templates derived

请考虑以下代码:

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)
    {
    }
};

唯一可用的构造函数是一个复制构造函数,它接受对基类型的const引用。 用法示例:

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

Visual C ++:

  

'的std :: basic_ios&LT; _Elem,_Traits&GT; :: basic_ios'   :无法访问私人会员   在课堂上宣布   '的std :: basic_ios&LT; _Elem,_Traits&GT;'

英特尔:

  

没有构造函数的实例   “标准:: basic_ofstream&LT; _Elem,   _Traits&gt; :: basic_ofstream [with _Elem = char,_Traits = std :: char_traits]“匹配参数列表

有人可以向我解释为什么这不起作用吗?

4 个答案:

答案 0 :(得分:4)

您无法复制流,因为它们的复制构造函数是私有的(或者更具体地说,是来自basic_ios的复制文件)。

另见this question

答案 1 :(得分:4)

STL流无法复制构建,这就是你的问题。

答案 2 :(得分:1)

如前所述,标准流不可复制。但是,在C ++ 0x中,它们是可移动的。根据您使用的编译器/设置,这可能是您看到的行为。 ofstream x(std::ofstream("x"));创建一个临时ofstream,然后将其临时移动到指定的ofstream中。这是完全合法的。但是,在代码中,您定义了一个复制构造函数,因此不能进行任何移动。副本仍然被禁止,因此编译器会阻止你。

所以,对于你的班级,你也必须移动,而不是复制。 ios_base_adaptor(base_type&& other) : ofstream(std::move(other)) { }

答案 3 :(得分:0)

好的,我想要实现的是创建任何basic_ios&lt;&gt;的可能性。我来自的课程。所以,在我的例子中,我只是想为指定的文件创建一个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));
    }
};

将指针传递给基类应该是安全的,因为在这个阶段它已经被分配和构建了。

用法:

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

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

还有其他解决方法吗?