2015-07-15 2 views
1

Я пытаюсь создать свой класс, который просто публично-производным от boost::asio::streambuf с некоторыми методами добавил:Выведение из `повышение :: ASIO :: streambuf`

class my_super_streambuf : public boost::asio::streambuf { 
public: 
    void my_super_method(); 
}; 

Но когда я просто заменить boost::asio::streambuf к my_super_streambuf там произошли ошибки:

error C2039: 'const_iterator' : is not a member of 'my_super_streambuf' 

в

D:\projects\my_super_streambuf\third-party\boost\boost/asio/impl/write.hpp(199) : 
see reference to class template instantiation 
'boost::asio::detail::consuming_buffers<boost::asio::const_buffer, 
ConstBufferSequence>' being compiled 

Как я могу правильно получить от boost::asio::streambuf?

+0

Как использовать 'my_super_streambuf'? Что такое 'ConstBufferSequence' в неудавшемся экземпляре? – aschepler

ответ

3

Проблема не с тем, как один происходит от boost::asio::streambuf. Вместо этого результирующая ошибка связана с тем, что компилятор выбирает перегрузку non-streambuf write(SyncWriteStream&, const ConstBufferSequence&) вместо write(SyncWriteStream&, basic_streambuf<Allocator>&). Чтобы решить эту проблему, можно явно привести объект, производный от boost::asio::streambuf к ссылке boost::asio::streambuf при вызове write():

class derived_streambuf 
    : public boost::asio::streambuf 
{}; 

// ... 

derived_streambuf streambuf; 
boost::asio::write(socket, static_cast<boost::asio::streambuf&>(streambuf)); 

Чтобы понять этот вопрос, рассмотрит заявление перегруженной функции в вопросе:

// ConstBufferSequence 
template< 
    typename SyncWriteStream, 
    typename ConstBufferSequence> 
std::size_t write(
    SyncWriteStream&, 
    const ConstBufferSequence&); 

// Streambuf 
template< 
    typename SyncWriteStream, 
    typename Allocator> 
std::size_t write(
    SyncWriteStream&, 
    basic_streambuf<Allocator>&); 

Если derived_streambuf предоставляется в качестве второго аргумента, создание функций приведет к:

// ConstBufferSequence 
std::size_t write(..., derived_streambuf&); 

// Streambuf 
std::size_t write(..., basic_streambuf<char>&); 

Что касается компилятора, то первое является лучшим совпадением, так как оно является точным совпадением и, следовательно, оно выбрано.


Вот полный пример demonstrating код, который составляет:

#include <boost/asio.hpp> 

// Derive from boost::asio::streambuf. 
class derived_streambuf 
    : public boost::asio::streambuf 
{}; 

// Helper function to force type. 
template <typename Allocator> 
boost::asio::basic_streambuf<Allocator>& 
as_streambuf(boost::asio::basic_streambuf<Allocator>& streambuf) 
{ 
    return streambuf; 
} 

int main() 
{ 
    boost::asio::io_service io_service; 
    boost::asio::ip::tcp::socket socket(io_service); 
    derived_streambuf streambuf; 
    boost::asio::write(socket, static_cast<boost::asio::streambuf&>(streambuf)); 
    boost::asio::write(socket, as_streambuf(streambuf)); 
} 
+0

Я думаю, можно утверждать, что перегрузки Boost.Asio 'write()' должны обновляться, чтобы предпочесть семейство перегрузок 'basic_streambuf', когда' basic_streambuf' является базой второго аргумент. –

0

Вы уверены, что есть «const_iterator» в качестве публичного участника «boost :: asio :: streambuf»?

я попробовал эту коду, и она работает:

class MyVector : public std::vector<int>{}; 
int main(int argc, const char * argv[]) { 
    MyVector v; 
    v.push_back(1); 
    for (MyVector::const_iterator iter = v.begin(); iter != v.end(); iter++) { 
     cout << *iter << endl; 
    } 
} 

, а также следующие:

class MyBase { 
    public: 
     typedef int base_int; 
}; 
class MyDerived : public MyBase {}; 

MyDerived::base_int P = 5; 
MyBase::base_int Q = 5; 
+0

Он говорит о 'streambuf', а не' vector' – PSIAlt

Смежные вопросы