Получите из аргумента шаблона и вызовите его конструктор копирования - PullRequest
2 голосов
/ 18 июня 2011

Обратите внимание на следующий код:

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> '

Intel:

нет экземпляра конструктора "std :: basic_ofstream <_Elem, _Traits> :: basic_ofstream [with _Elem = char,_Traits = std :: char_traits] "соответствует списку аргументов

Может кто-нибудь объяснить мне, почему это не работает?

Ответы [ 4 ]

4 голосов
/ 18 июня 2011

STL-потоки не могут быть созданы с помощью копирования, вот ваша проблема.

4 голосов
/ 18 июня 2011

Вы не можете копировать потоки, потому что их конструктор копирования является личным (или, более конкретно, копирует ctor из basic_ios).

См. Также этот вопрос .

1 голос
/ 18 июня 2011

Как уже было сказано, стандартные потоки не копируются. Однако в C ++ 0x они подвижны . В зависимости от того, какой компилятор / настройки вы используете, это, вероятно, поведение, которое вы видите. ofstream x(std::ofstream("x")); создает временный ofstream, а затем перемещает его в именованный ofstream. Это совершенно законно. Однако в вашем коде вы определяете конструктор копирования, поэтому перемещение невозможно. Копии по-прежнему запрещены, поэтому компилятор останавливает вас.

Итак, для вашего класса вам также придется двигаться, а не копировать. ios_base_adaptor(base_type&& other) : ofstream(std::move(other)) { }

0 голосов
/ 18 июня 2011

Хорошо, чего я хочу добиться, так это возможности создать любой класс 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));
    }
};

Надежнее передать указатель на базовый класс, потому что на этом этапе он уже выделен и создан.

Использование:

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

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

Любой другой обходной путь?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...