C++ "Hello World" Boost Tee Example Program

C++ hello world Boost tee example program

Based on help from the question John linked:

#include <boost/iostreams/tee.hpp>
#include <boost/iostreams/stream.hpp>
#include <fstream>
#include <iostream>

using std::ostream;
using std::ofstream;
using std::cout;

namespace bio = boost::iostreams;
using bio::tee_device;
using bio::stream;

int main()
{
typedef tee_device<ostream, ofstream> TeeDevice;
typedef stream<TeeDevice> TeeStream;
ofstream ofs("sample.txt");
TeeDevice my_tee(cout, ofs);
TeeStream my_split(my_tee);
my_split << "Hello, World!\n";
my_split.flush();
my_split.close();
}

Any way to wrap construction of boost tee stream for automatic type deduction?

Compile fine in c++17 with "guaranty copy elision".

In c++11, you might use return {..}:

template <typename StreamT1, typename StreamT2>
boost::iostreams::stream<boost::iostreams::tee_device<StreamT1, StreamT2> >
make_tee(StreamT1 & t1, StreamT2 & t2)
{
using boost::iostreams::stream;
using boost::iostreams::tee;
return {tee(t1,t2)};
}

Demo

Using boost::iostreams::tee_device?

You use the constructor-forwarding version of io::stream, which construct a tee-stream itself and forward all arguments to that. C++03 has only limited capabilities when it comes to forwarding arguments to functions (amount of overloads needed easily grow exponentially). It (io::stream) makes the following restrictions:

Each of these members constructs an instance of stream and associates it with an instance of the Device T constructed from the given lists of arguments. The T constructors involved must take all arguments by value or const reference.

Well, but the tee_device constructor says

Constructs an instance of tee_device based on the given pair of Sinks. Each function parameter is a non-const reference if the corresponding template argument is a stream or stream buffer type, and a const reference otherwise.

That won't work, of course. io::stream provides another constructor that takes a T as first argument. This works here (Compiles, at least. The assertion fails, though. I've not worked with boost::iostreams so i can't help with that)

namespace io = boost::iostreams;
typedef io::tee_device<std::stringstream, std::stringstream> TeeDevice;
typedef io::stream< TeeDevice > TeeStream;
std::stringstream ss1, ss2;
TeeDevice my_tee(ss1, ss2);
TeeStream my_split(my_tee);
my_split << "Testing";
assert(ss1.str() == "Testing" && ss1.str() == ss2.str());

Edit: After calling flush() or streaming << std::flush, the assertion passes.

Tee-ing input (cin) out to a log file (or clog)

Final Answer:

#ifndef TEE_ISTREAM_H_
#define TEE_ISTREAM_H_

/*****************************************************************************/

#include <boost/iostreams/tee.hpp>
#include <boost/iostreams/invert.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/tr1/memory.hpp>
#include <iostream>

/*****************************************************************************/

namespace bio = boost::iostreams;

/*****************************************************************************/

class tee_source : public bio::source {
public:
tee_source( std::istream & in, const std::string & filename )
: in_(in), log_file_(filename, std::ios::app), tee_(bio::tee(log_file_), 1)
{ }

std::streamsize read(char* s, std::streamsize n)
{
return tee_.read(in_,s,n);
}

private:
std::istream & in_;
bio::file log_file_;
bio::inverse< bio::tee_filter< bio::file > > tee_;
};

/*****************************************************************************/

typedef bio::filtering_istream tee_istream_t;
typedef std::tr1::shared_ptr< tee_istream_t > tee_istream_ptr_t;

/*****************************************************************************/

inline tee_istream_ptr_t make_tee_istream( std::istream & in, const std::string & filename )
{
return tee_istream_ptr_t( new tee_istream_t( tee_source( in , filename ), 0 ) );
}

/*****************************************************************************/

#endif

hello world python extension in c++ using boost?

/usr/include/boost/python/detail/wrap_python.hpp:50:23:
fatal error: pyconfig.h: No such file
or directory compilation terminated.

This line tells exactly why it doesn't work. Your compiler doesn't know where is the pyconfig.h file. You have two options here:

  1. place pyconfig.h in a location that
    g++ knows about (i.e. your
    project's directory)
  2. add -I DIRECTORY (this is capital i,
    not lowercase L) flag to g++ that
    will make g++ search DIRECTORY for header files

g++ -I /path/to/my/include/files main.cpp

Boost::Test : Compiling and running a hello world program

You might need to add #define BOOST_TEST_DYN_LINK before Boost.Test include.

Check here - if library was built as dynamic (and it is usually so in many linux distributions), this macro is required. It makes header file define int main() - with static linking main is defined inside static library, but dynamic linking requires main to be in 'static' part of program. So this macro will make boost header 'inject' main into your cpp file and after compilation it will be there.

Boost Python Hello World example not working in Python

AFAIK you have to change the extension of the DLL to .pyd or otherwise Python will not be able to load it. I think you can set a build option to automatically set the extension in VS, but I don't know for sure.

Also, make sure that the created extension is somewhere on the PYTHONPATH, the path, python will look for modules to load.

Error in compilation of Hello World program

Remove the line numbers, that's the problem.



Related Topics



Leave a reply



Submit