Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;boost::任何定义我自己的打印,_C++_Boost Any - Fatal编程技术网

C++ c++;boost::任何定义我自己的打印,

C++ c++;boost::任何定义我自己的打印,,c++,boost-any,C++,Boost Any,我一直在努力寻找如何使用boost::any创建一个打印函数,该函数可以首先使用模板打印任何类型 template <typename T> struct printer { void print(ostream& os, const boost::any& a); }; 模板 结构打印机{ 无效打印(ostream&os,const boost::any&a); }; 我需要先定义print()。 我希望让真正的操作员查看Boost邮件列表上的此线程

我一直在努力寻找如何使用
boost::any
创建一个打印函数,该函数可以首先使用模板打印任何类型

template <typename T>
struct printer {
    void print(ostream& os, const boost::any& a);
}; 
模板
结构打印机{
无效打印(ostream&os,const boost::any&a);
}; 
我需要先定义
print()

我希望让真正的
操作员查看Boost邮件列表上的此线程:


它有一些想法,其中一些看起来还行,而另一些(对我来说)则不行。不过,总体而言,这似乎是一项很难以一般方式完成的任务,因为(如该线程中所述),某些类型永远不可能是ostream'able,但可以包含在
boost::any
对象中。

有一种非常简单的方法可以做到这一点,如“”:

struct拖缆{
虚拟无效打印(ostream&o,const boost::any&a)const=0;
虚拟拖缆*clone()常量=0;
虚拟~streamer(){}
};
模板
struct streamer\u impl:拖缆{
void print(ostream&o,const boost::any&a)const{o clone():0),o_(a.o_){
模板
any_out&运算符=(const T&r){
任何输出(r)。交换(*本);
归还*这个;
}
~any_out(){删除拖缆}

friend std::ostream&operator我这样做,我认为这样做既干净又安全:

任何_extension.hpp:

namespace cpputil
{

struct AnyWriter
{
    /// Register a type with the AnyWriter.
    /// @pre T must have an ostream << operator available somewhere
    template<class T> static bool registerType()
    {
        return registeredTypes().emplace(std::type_index(typeid(T)),
                                         std::bind(&AnyWriter::write<T>,
                                                   std::placeholders::_1,
                                                   std::placeholders::_2)).second;
    }

    /// Write any registred object to a stream
    /// @pre Underlying type must have been registered with a call to AnyWriter::registerType<T>
    /// @param os is reference to a std::ostream
    /// @param anyObject is a reference to a boost::any
    static void writeAny(std::ostream& os, const boost::any& anyObject);
private:

    // A function object that converts an any to a type and streams it to an ostream
    using WriteFunction = std::function<void (std::ostream&, const boost::any&)>;

    // a map of typeinfo to WriteFunction
    using RegisteredTypes = std::unordered_map<std::type_index, WriteFunction >;

    // retrieve the WriteFunction map in a safe way
    static RegisteredTypes& registeredTypes();

    // Convert an any to a type, and write it to a stream
    template<class T> static void write(std::ostream& os, const boost::any& anyObject) {
        try {
            const T& typedObject = boost::any_cast<const T&>(anyObject);
            os << typedObject;
        }
        catch(boost::bad_any_cast& e) {
            os << "<exception in conversion: " << e.what() << ">";
        }
    }

};
}

namespace std {
    ostream& operator<<(ostream& os, const ::boost::any& anyObject);
}
名称空间cpputil
{
结构任意编写器
{
///向AnyWriter注册类型。

///@pre T必须有一个由Pawel Zubrycki(提到Björn Karlsson的书)给出的非常好的答案

但代码在以下几行中有一些错误:

// ...
o << *boost::any_cast<T>(a);    // should be:   o << *boost::any_cast<T>(&a);
// ...
a.streamer_->print(o, a);       // should be:   a.streamer_->print(o, a.o_);
如果我们将拖缆实例化为

new streamer_impl<T>()
…这是一个解决方案

另一种解决方案是保留引用并调整
streamer\u impl
的模板实例化。请参见下文

以下推荐的解决方案是:

#ifndef ANY_OUT_H
#define ANY_OUT_H

#include <iostream>
#include <boost/any.hpp>

struct streamer {
  virtual void print(std::ostream &o, const boost::any &a) const =0;
  virtual streamer * clone() const = 0;
  virtual ~streamer() {}
};

template <class T>
struct streamer_impl: streamer{
  void print(std::ostream &o, const boost::any &a) const { o << boost::any_cast<T>(a); }
  streamer *clone() const { return new streamer_impl<T>(); }
};

class any_out {
  boost::any o_;
  streamer *streamer_;
  void swap(any_out & r){
    std::swap(streamer_, r.streamer_);
    std::swap(o_, r.o_);
  }
public:
  any_out(): streamer_(0) {}

  template<class T> any_out(const T& value)
    : o_(value),
#if 1
      streamer_(new streamer_impl<typename std::decay<decltype(value)>::type>)
#else
      streamer_((o_.type() == typeid(const char *))
                ? static_cast<streamer *>(new streamer_impl<const char *>)
                : static_cast<streamer *>(new streamer_impl<T>))
#endif
  {
  }

  // template<class T> any_out(const T value)
  //   : o_(value),
  //     streamer_(new streamer_impl<T>)
  // {
  // }

  any_out(const any_out& a)
    : o_(a.o_), streamer_(a.streamer_ ? a.streamer_->clone() : 0) {}

  template <class T>
  any_out & operator=(const T& r) {
    any_out(r).swap(*this);
    return *this;
  }
  ~any_out() { delete streamer_; }

  friend std::ostream &operator<<(std::ostream& o, const any_out & a);
};

std::ostream &operator<<(std::ostream& o, const any_out & a) {
  if(a.streamer_)
    a.streamer_->print(o, a.o_);
  return o;
}

#endif
#如果有
#定义任何输出
#包括
#包括
结构拖缆{
虚拟无效打印(标准::ostream&o,常数boost::任意&a)常数=0;
虚拟拖缆*clone()常量=0;
虚拟~streamer(){}
};
模板
struct streamer\u impl:拖缆{
void print(std::ostream&o,const boost::any&a)const{o clone():0{}
模板
任意输出和运算符=(常数T&r){
任何输出(r)。交换(*本);
归还*这个;
}
~any_out(){删除拖缆}

friend std::ostream&Operator谢谢你给我寄来这个解决方案你太棒了,Karlsson先生(这本书的作者)太棒了。我刚刚想起他的书中有解决这个问题的方法。我很高兴我能帮上忙。
// ...
o << *boost::any_cast<T>(a);    // should be:   o << *boost::any_cast<T>(&a);
// ...
a.streamer_->print(o, a);       // should be:   a.streamer_->print(o, a.o_);
#ifndef ANY_OUT_H
#define ANY_OUT_H

#include <iostream>
#include <boost/any.hpp>

struct streamer {
  virtual void print(std::ostream &o, const boost::any &a) const =0;
  virtual streamer * clone() const = 0;
  virtual ~streamer() {}
};

template <class T>
struct streamer_impl: streamer{
  void print(std::ostream &o, const boost::any &a) const { o << *boost::any_cast<T>(&a); }
  streamer *clone() const { return new streamer_impl<T>(); }
};

class any_out {
  streamer *streamer_;
  boost::any o_;
  void swap(any_out & r){
    std::swap(streamer_, r.streamer_);
    std::swap(o_, r.o_);
  }
public:
  any_out(): streamer_(0) {}
  template<class T> any_out(const T& value)
    : streamer_(new streamer_impl<T>()), o_(value) {}
  any_out(const any_out& a)
    : streamer_(a.streamer_ ? a.streamer_->clone() : 0), o_(a.o_) {}

  template <class T>
  any_out & operator=(const T& r) {
    any_out(r).swap(*this);
    return *this;
  }
  ~any_out() { delete streamer_; }

  friend std::ostream &operator<<(std::ostream& o, const any_out & a);
};

std::ostream &operator<<(std::ostream& o, const any_out & a) {
  if(a.streamer_)
    a.streamer_->print(o, a.o_);
  return o;
}

#endif
{
   any_out a = 5;
   std::cout << a << std::endl;
}
int main()
{
  char str[] = "mystring";
  any_out a = str;
  std::cout << a << std::endl;

  a = "myconststring";
  std::cout << a << std::endl;
}
any_out(const T& value)
new streamer_impl<T>()
  any_out(const T value)
#ifndef ANY_OUT_H
#define ANY_OUT_H

#include <iostream>
#include <boost/any.hpp>

struct streamer {
  virtual void print(std::ostream &o, const boost::any &a) const =0;
  virtual streamer * clone() const = 0;
  virtual ~streamer() {}
};

template <class T>
struct streamer_impl: streamer{
  void print(std::ostream &o, const boost::any &a) const { o << boost::any_cast<T>(a); }
  streamer *clone() const { return new streamer_impl<T>(); }
};

class any_out {
  boost::any o_;
  streamer *streamer_;
  void swap(any_out & r){
    std::swap(streamer_, r.streamer_);
    std::swap(o_, r.o_);
  }
public:
  any_out(): streamer_(0) {}

  template<class T> any_out(const T& value)
    : o_(value),
#if 1
      streamer_(new streamer_impl<typename std::decay<decltype(value)>::type>)
#else
      streamer_((o_.type() == typeid(const char *))
                ? static_cast<streamer *>(new streamer_impl<const char *>)
                : static_cast<streamer *>(new streamer_impl<T>))
#endif
  {
  }

  // template<class T> any_out(const T value)
  //   : o_(value),
  //     streamer_(new streamer_impl<T>)
  // {
  // }

  any_out(const any_out& a)
    : o_(a.o_), streamer_(a.streamer_ ? a.streamer_->clone() : 0) {}

  template <class T>
  any_out & operator=(const T& r) {
    any_out(r).swap(*this);
    return *this;
  }
  ~any_out() { delete streamer_; }

  friend std::ostream &operator<<(std::ostream& o, const any_out & a);
};

std::ostream &operator<<(std::ostream& o, const any_out & a) {
  if(a.streamer_)
    a.streamer_->print(o, a.o_);
  return o;
}

#endif
int main()
{
  char str[] = "mystring";
  any_out a = str;
  std::cout << a << std::endl;

  a = "myconststring";
  std::cout << a << std::endl;
}