boost::any 替换下面的代码

boost::any replacement for the code below

我希望摆脱对我的代码的 boost 依赖。我有以下结构构造。在代码中的另一个位置调用和使用此结构时,使用 boost::any_cast。我知道模板类会做到这一点,但很难编写这个模板。 - C 菜鸟。

struct Properties {

public:

Properties() {}

Properties(const std::string &s, const boost::any & p) {

   name = s;

   value = p;

}



template <typename T>

Properties(T n) {

   value = n;

}

boost::any value;



std::string name;

};

//////////////////////////////////////////

// my_any.hpp

#include <memory>

#include <stdexcept>



struct my_any

{

  my_any() = default;

  template <typename T> my_any(T const& v) : _storage(new storage< T >(v)) { }

  my_any(my_any const& other)       : _storage(other._storage? std::move(other._storage->clone()) : nullptr) {}



  void swap(my_any& other)        { _storage.swap(other._storage); }

  friend void swap(my_any& a, my_any& b) { a.swap(b); };

  my_any& operator=(my_any other)    { swap(other); return *this; }



  // todo move semantics

private:

  struct storage_base { 

    virtual std::unique_ptr<storage_base> clone() = 0;

    virtual ~storage_base() = default; 

  };

  template <typename T>

  struct storage : storage_base {

    T value;

    explicit storage(T const& v) : value(v) {}

    std::unique_ptr<storage_base> clone() { return std::unique_ptr<storage_base>(new storage< T >(value)); }

  };

  std::unique_ptr<storage_base> _storage;

  template<typename T> friend T   & any_cast(my_any   &);

  template<typename T> friend T const& any_cast(my_any const&);

};



template <typename T> T& any_cast(my_any& a) { 

  if (auto p = dynamic_cast<my_any::storage< T >*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}



template <typename T> T const& any_cast(my_any const& a) { 

  if (auto p = dynamic_cast<my_any::storage< T > const*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}

struct Properties {

  public:

    Properties(const std::string &s="", const my_any& p={}) 

      : name(s), value(p) {}



    template <typename T> Properties(T n) { value = n; }



    std::string name;

    my_any value;

};



#include <vector>

#include <iostream>



typedef std::vector<Properties> Props;



int main()

{

  Props v;

  v.emplace_back("bye", 42);

  v.emplace_back("vector", v);



  std::cout <<"v.size():"     << v.size()              <<"\

";

  std::cout <<"v[0].value:"    << any_cast<int>(v[0].value)     <<"\

";

  std::cout <<"v[1].value.size():" << any_cast<Props>(v[1].value).size() <<"\

";



  v[0].value = v;



  try {

    std::cout <<"v[0].value:" << any_cast<int>(v[0].value) <<"\

";

  } catch(std::exception const& e)

  {

    std::cout << e.what() <<" exception caught, ok!\

";

  }



  std::cout <<"v[0].value.size():" << any_cast<Props>(v[0].value).size() <<"\

";

}
Properties p("int", 42);

std::cout << boost::any_cast<int>(p.value) << '\

';

p = Properties("string", std::string("hello"));

std::cout << boost::any_cast<std::string>(p.value) << '\

';

template<typename T>

struct Properties {

public:

Properties() {}

Properties(std::string s, T p)

: name(std::move(s))  // should use initialization list instead

, value(std::move(p)) // of assignment within the body

{}



Properties(T n)

: value(std::move(n))

{}



std::string name;

T value;

};
Properties<int> p("int", 42);

std::cout << p.value << '\

';

// p = Properties<std::string>("string", std::string("hello"));

// will not compile because Properties<int> and Properties<std::string> are

// distinct types

只是为了好玩,我想我会创建一个极简的任何实现:

struct Properties {

public:

Properties() {}

Properties(const std::string &s, const boost::any & p) {

   name = s;

   value = p;

}



template <typename T>

Properties(T n) {

   value = n;

}

boost::any value;



std::string name;

};

//////////////////////////////////////////

// my_any.hpp

#include <memory>

#include <stdexcept>



struct my_any

{

  my_any() = default;

  template <typename T> my_any(T const& v) : _storage(new storage< T >(v)) { }

  my_any(my_any const& other)       : _storage(other._storage? std::move(other._storage->clone()) : nullptr) {}



  void swap(my_any& other)        { _storage.swap(other._storage); }

  friend void swap(my_any& a, my_any& b) { a.swap(b); };

  my_any& operator=(my_any other)    { swap(other); return *this; }



  // todo move semantics

private:

  struct storage_base { 

    virtual std::unique_ptr<storage_base> clone() = 0;

    virtual ~storage_base() = default; 

  };

  template <typename T>

  struct storage : storage_base {

    T value;

    explicit storage(T const& v) : value(v) {}

    std::unique_ptr<storage_base> clone() { return std::unique_ptr<storage_base>(new storage< T >(value)); }

  };

  std::unique_ptr<storage_base> _storage;

  template<typename T> friend T   & any_cast(my_any   &);

  template<typename T> friend T const& any_cast(my_any const&);

};



template <typename T> T& any_cast(my_any& a) { 

  if (auto p = dynamic_cast<my_any::storage< T >*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}



template <typename T> T const& any_cast(my_any const& a) { 

  if (auto p = dynamic_cast<my_any::storage< T > const*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}

struct Properties {

  public:

    Properties(const std::string &s="", const my_any& p={}) 

      : name(s), value(p) {}



    template <typename T> Properties(T n) { value = n; }



    std::string name;

    my_any value;

};



#include <vector>

#include <iostream>



typedef std::vector<Properties> Props;



int main()

{

  Props v;

  v.emplace_back("bye", 42);

  v.emplace_back("vector", v);



  std::cout <<"v.size():"     << v.size()              <<"\

";

  std::cout <<"v[0].value:"    << any_cast<int>(v[0].value)     <<"\

";

  std::cout <<"v[1].value.size():" << any_cast<Props>(v[1].value).size() <<"\

";



  v[0].value = v;



  try {

    std::cout <<"v[0].value:" << any_cast<int>(v[0].value) <<"\

";

  } catch(std::exception const& e)

  {

    std::cout << e.what() <<" exception caught, ok!\

";

  }



  std::cout <<"v[0].value.size():" << any_cast<Props>(v[0].value).size() <<"\

";

}
Properties p("int", 42);

std::cout << boost::any_cast<int>(p.value) << '\

';

p = Properties("string", std::string("hello"));

std::cout << boost::any_cast<std::string>(p.value) << '\

';

template<typename T>

struct Properties {

public:

Properties() {}

Properties(std::string s, T p)

: name(std::move(s))  // should use initialization list instead

, value(std::move(p)) // of assignment within the body

{}



Properties(T n)

: value(std::move(n))

{}



std::string name;

T value;

};
Properties<int> p("int", 42);

std::cout << p.value << '\

';

// p = Properties<std::string>("string", std::string("hello"));

// will not compile because Properties<int> and Properties<std::string> are

// distinct types

然后您可以按照您的用例所示的方式使用它:

struct Properties {

public:

Properties() {}

Properties(const std::string &s, const boost::any & p) {

   name = s;

   value = p;

}



template <typename T>

Properties(T n) {

   value = n;

}

boost::any value;



std::string name;

};

//////////////////////////////////////////

// my_any.hpp

#include <memory>

#include <stdexcept>



struct my_any

{

  my_any() = default;

  template <typename T> my_any(T const& v) : _storage(new storage< T >(v)) { }

  my_any(my_any const& other)       : _storage(other._storage? std::move(other._storage->clone()) : nullptr) {}



  void swap(my_any& other)        { _storage.swap(other._storage); }

  friend void swap(my_any& a, my_any& b) { a.swap(b); };

  my_any& operator=(my_any other)    { swap(other); return *this; }



  // todo move semantics

private:

  struct storage_base { 

    virtual std::unique_ptr<storage_base> clone() = 0;

    virtual ~storage_base() = default; 

  };

  template <typename T>

  struct storage : storage_base {

    T value;

    explicit storage(T const& v) : value(v) {}

    std::unique_ptr<storage_base> clone() { return std::unique_ptr<storage_base>(new storage< T >(value)); }

  };

  std::unique_ptr<storage_base> _storage;

  template<typename T> friend T   & any_cast(my_any   &);

  template<typename T> friend T const& any_cast(my_any const&);

};



template <typename T> T& any_cast(my_any& a) { 

  if (auto p = dynamic_cast<my_any::storage< T >*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}



template <typename T> T const& any_cast(my_any const& a) { 

  if (auto p = dynamic_cast<my_any::storage< T > const*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}

struct Properties {

  public:

    Properties(const std::string &s="", const my_any& p={}) 

      : name(s), value(p) {}



    template <typename T> Properties(T n) { value = n; }



    std::string name;

    my_any value;

};



#include <vector>

#include <iostream>



typedef std::vector<Properties> Props;



int main()

{

  Props v;

  v.emplace_back("bye", 42);

  v.emplace_back("vector", v);



  std::cout <<"v.size():"     << v.size()              <<"\

";

  std::cout <<"v[0].value:"    << any_cast<int>(v[0].value)     <<"\

";

  std::cout <<"v[1].value.size():" << any_cast<Props>(v[1].value).size() <<"\

";



  v[0].value = v;



  try {

    std::cout <<"v[0].value:" << any_cast<int>(v[0].value) <<"\

";

  } catch(std::exception const& e)

  {

    std::cout << e.what() <<" exception caught, ok!\

";

  }



  std::cout <<"v[0].value.size():" << any_cast<Props>(v[0].value).size() <<"\

";

}
Properties p("int", 42);

std::cout << boost::any_cast<int>(p.value) << '\

';

p = Properties("string", std::string("hello"));

std::cout << boost::any_cast<std::string>(p.value) << '\

';

template<typename T>

struct Properties {

public:

Properties() {}

Properties(std::string s, T p)

: name(std::move(s))  // should use initialization list instead

, value(std::move(p)) // of assignment within the body

{}



Properties(T n)

: value(std::move(n))

{}



std::string name;

T value;

};
Properties<int> p("int", 42);

std::cout << p.value << '\

';

// p = Properties<std::string>("string", std::string("hello"));

// will not compile because Properties<int> and Properties<std::string> are

// distinct types

查看输出 Live On Coliru


boost::any 使用类型擦除来存储任何类型的对象,您可以在运行时为其分配不同类型的值。 any_cast 用于检索存储在 any 对象中的具有正确类型的原始值。例如,您当前的课程允许您这样做

struct Properties {

public:

Properties() {}

Properties(const std::string &s, const boost::any & p) {

   name = s;

   value = p;

}



template <typename T>

Properties(T n) {

   value = n;

}

boost::any value;



std::string name;

};

//////////////////////////////////////////

// my_any.hpp

#include <memory>

#include <stdexcept>



struct my_any

{

  my_any() = default;

  template <typename T> my_any(T const& v) : _storage(new storage< T >(v)) { }

  my_any(my_any const& other)       : _storage(other._storage? std::move(other._storage->clone()) : nullptr) {}



  void swap(my_any& other)        { _storage.swap(other._storage); }

  friend void swap(my_any& a, my_any& b) { a.swap(b); };

  my_any& operator=(my_any other)    { swap(other); return *this; }



  // todo move semantics

private:

  struct storage_base { 

    virtual std::unique_ptr<storage_base> clone() = 0;

    virtual ~storage_base() = default; 

  };

  template <typename T>

  struct storage : storage_base {

    T value;

    explicit storage(T const& v) : value(v) {}

    std::unique_ptr<storage_base> clone() { return std::unique_ptr<storage_base>(new storage< T >(value)); }

  };

  std::unique_ptr<storage_base> _storage;

  template<typename T> friend T   & any_cast(my_any   &);

  template<typename T> friend T const& any_cast(my_any const&);

};



template <typename T> T& any_cast(my_any& a) { 

  if (auto p = dynamic_cast<my_any::storage< T >*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}



template <typename T> T const& any_cast(my_any const& a) { 

  if (auto p = dynamic_cast<my_any::storage< T > const*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}

struct Properties {

  public:

    Properties(const std::string &s="", const my_any& p={}) 

      : name(s), value(p) {}



    template <typename T> Properties(T n) { value = n; }



    std::string name;

    my_any value;

};



#include <vector>

#include <iostream>



typedef std::vector<Properties> Props;



int main()

{

  Props v;

  v.emplace_back("bye", 42);

  v.emplace_back("vector", v);



  std::cout <<"v.size():"     << v.size()              <<"\

";

  std::cout <<"v[0].value:"    << any_cast<int>(v[0].value)     <<"\

";

  std::cout <<"v[1].value.size():" << any_cast<Props>(v[1].value).size() <<"\

";



  v[0].value = v;



  try {

    std::cout <<"v[0].value:" << any_cast<int>(v[0].value) <<"\

";

  } catch(std::exception const& e)

  {

    std::cout << e.what() <<" exception caught, ok!\

";

  }



  std::cout <<"v[0].value.size():" << any_cast<Props>(v[0].value).size() <<"\

";

}
Properties p("int", 42);

std::cout << boost::any_cast<int>(p.value) << '\

';

p = Properties("string", std::string("hello"));

std::cout << boost::any_cast<std::string>(p.value) << '\

';

template<typename T>

struct Properties {

public:

Properties() {}

Properties(std::string s, T p)

: name(std::move(s))  // should use initialization list instead

, value(std::move(p)) // of assignment within the body

{}



Properties(T n)

: value(std::move(n))

{}



std::string name;

T value;

};
Properties<int> p("int", 42);

std::cout << p.value << '\

';

// p = Properties<std::string>("string", std::string("hello"));

// will not compile because Properties<int> and Properties<std::string> are

// distinct types

您不能只是将上面的类转换为模板并获得相同的功能。如果这样做,您将只能存储一种类型的值。而且您必须将整个 struct 更改为模板,而不仅仅是构造函数。

struct Properties {

public:

Properties() {}

Properties(const std::string &s, const boost::any & p) {

   name = s;

   value = p;

}



template <typename T>

Properties(T n) {

   value = n;

}

boost::any value;



std::string name;

};

//////////////////////////////////////////

// my_any.hpp

#include <memory>

#include <stdexcept>



struct my_any

{

  my_any() = default;

  template <typename T> my_any(T const& v) : _storage(new storage< T >(v)) { }

  my_any(my_any const& other)       : _storage(other._storage? std::move(other._storage->clone()) : nullptr) {}



  void swap(my_any& other)        { _storage.swap(other._storage); }

  friend void swap(my_any& a, my_any& b) { a.swap(b); };

  my_any& operator=(my_any other)    { swap(other); return *this; }



  // todo move semantics

private:

  struct storage_base { 

    virtual std::unique_ptr<storage_base> clone() = 0;

    virtual ~storage_base() = default; 

  };

  template <typename T>

  struct storage : storage_base {

    T value;

    explicit storage(T const& v) : value(v) {}

    std::unique_ptr<storage_base> clone() { return std::unique_ptr<storage_base>(new storage< T >(value)); }

  };

  std::unique_ptr<storage_base> _storage;

  template<typename T> friend T   & any_cast(my_any   &);

  template<typename T> friend T const& any_cast(my_any const&);

};



template <typename T> T& any_cast(my_any& a) { 

  if (auto p = dynamic_cast<my_any::storage< T >*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}



template <typename T> T const& any_cast(my_any const& a) { 

  if (auto p = dynamic_cast<my_any::storage< T > const*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}

struct Properties {

  public:

    Properties(const std::string &s="", const my_any& p={}) 

      : name(s), value(p) {}



    template <typename T> Properties(T n) { value = n; }



    std::string name;

    my_any value;

};



#include <vector>

#include <iostream>



typedef std::vector<Properties> Props;



int main()

{

  Props v;

  v.emplace_back("bye", 42);

  v.emplace_back("vector", v);



  std::cout <<"v.size():"     << v.size()              <<"\

";

  std::cout <<"v[0].value:"    << any_cast<int>(v[0].value)     <<"\

";

  std::cout <<"v[1].value.size():" << any_cast<Props>(v[1].value).size() <<"\

";



  v[0].value = v;



  try {

    std::cout <<"v[0].value:" << any_cast<int>(v[0].value) <<"\

";

  } catch(std::exception const& e)

  {

    std::cout << e.what() <<" exception caught, ok!\

";

  }



  std::cout <<"v[0].value.size():" << any_cast<Props>(v[0].value).size() <<"\

";

}
Properties p("int", 42);

std::cout << boost::any_cast<int>(p.value) << '\

';

p = Properties("string", std::string("hello"));

std::cout << boost::any_cast<std::string>(p.value) << '\

';

template<typename T>

struct Properties {

public:

Properties() {}

Properties(std::string s, T p)

: name(std::move(s))  // should use initialization list instead

, value(std::move(p)) // of assignment within the body

{}



Properties(T n)

: value(std::move(n))

{}



std::string name;

T value;

};
Properties<int> p("int", 42);

std::cout << p.value << '\

';

// p = Properties<std::string>("string", std::string("hello"));

// will not compile because Properties<int> and Properties<std::string> are

// distinct types

但是,我上面发布的代码现在是非法的。

struct Properties {

public:

Properties() {}

Properties(const std::string &s, const boost::any & p) {

   name = s;

   value = p;

}



template <typename T>

Properties(T n) {

   value = n;

}

boost::any value;



std::string name;

};

//////////////////////////////////////////

// my_any.hpp

#include <memory>

#include <stdexcept>



struct my_any

{

  my_any() = default;

  template <typename T> my_any(T const& v) : _storage(new storage< T >(v)) { }

  my_any(my_any const& other)       : _storage(other._storage? std::move(other._storage->clone()) : nullptr) {}



  void swap(my_any& other)        { _storage.swap(other._storage); }

  friend void swap(my_any& a, my_any& b) { a.swap(b); };

  my_any& operator=(my_any other)    { swap(other); return *this; }



  // todo move semantics

private:

  struct storage_base { 

    virtual std::unique_ptr<storage_base> clone() = 0;

    virtual ~storage_base() = default; 

  };

  template <typename T>

  struct storage : storage_base {

    T value;

    explicit storage(T const& v) : value(v) {}

    std::unique_ptr<storage_base> clone() { return std::unique_ptr<storage_base>(new storage< T >(value)); }

  };

  std::unique_ptr<storage_base> _storage;

  template<typename T> friend T   & any_cast(my_any   &);

  template<typename T> friend T const& any_cast(my_any const&);

};



template <typename T> T& any_cast(my_any& a) { 

  if (auto p = dynamic_cast<my_any::storage< T >*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}



template <typename T> T const& any_cast(my_any const& a) { 

  if (auto p = dynamic_cast<my_any::storage< T > const*>(a._storage.get()))

    return p->value;

  else

    throw std::bad_cast();

}

struct Properties {

  public:

    Properties(const std::string &s="", const my_any& p={}) 

      : name(s), value(p) {}



    template <typename T> Properties(T n) { value = n; }



    std::string name;

    my_any value;

};



#include <vector>

#include <iostream>



typedef std::vector<Properties> Props;



int main()

{

  Props v;

  v.emplace_back("bye", 42);

  v.emplace_back("vector", v);



  std::cout <<"v.size():"     << v.size()              <<"\

";

  std::cout <<"v[0].value:"    << any_cast<int>(v[0].value)     <<"\

";

  std::cout <<"v[1].value.size():" << any_cast<Props>(v[1].value).size() <<"\

";



  v[0].value = v;



  try {

    std::cout <<"v[0].value:" << any_cast<int>(v[0].value) <<"\

";

  } catch(std::exception const& e)

  {

    std::cout << e.what() <<" exception caught, ok!\

";

  }



  std::cout <<"v[0].value.size():" << any_cast<Props>(v[0].value).size() <<"\

";

}
Properties p("int", 42);

std::cout << boost::any_cast<int>(p.value) << '\

';

p = Properties("string", std::string("hello"));

std::cout << boost::any_cast<std::string>(p.value) << '\

';

template<typename T>

struct Properties {

public:

Properties() {}

Properties(std::string s, T p)

: name(std::move(s))  // should use initialization list instead

, value(std::move(p)) // of assignment within the body

{}



Properties(T n)

: value(std::move(n))

{}



std::string name;

T value;

};
Properties<int> p("int", 42);

std::cout << p.value << '\

';

// p = Properties<std::string>("string", std::string("hello"));

// will not compile because Properties<int> and Properties<std::string> are

// distinct types

如果这些限制没问题,那么修改后的定义应该适合你。


相关推荐

  • Spring部署设置openshift

    Springdeploymentsettingsopenshift我有一个问题让我抓狂了三天。我根据OpenShift帐户上的教程部署了spring-eap6-quickstart代码。我已配置调试选项,并且已将Eclipse工作区与OpehShift服务器同步-服务器上的一切工作正常,但在Eclipse中出现无法消除的错误。我有这个错误:cvc-complex-type.2.4.a:Invali…
    2025-04-161
  • 检查Java中正则表达式中模式的第n次出现

    CheckfornthoccurrenceofpatterninregularexpressioninJava本问题已经有最佳答案,请猛点这里访问。我想使用Java正则表达式检查输入字符串中特定模式的第n次出现。你能建议怎么做吗?这应该可以工作:MatchResultfindNthOccurance(intn,Patternp,CharSequencesrc){Matcherm=p.matcher…
    2025-04-161
  • 如何让 JTable 停留在已编辑的单元格上

    HowtohaveJTablestayingontheeditedcell如果有人编辑JTable的单元格内容并按Enter,则内容会被修改并且表格选择会移动到下一行。是否可以禁止JTable在单元格编辑后转到下一行?原因是我的程序使用ListSelectionListener在单元格选择上同步了其他一些小部件,并且我不想在编辑当前单元格后选择下一行。Enter的默认绑定是名为selectNext…
    2025-04-161
  • Weblogic 12c 部署

    Weblogic12cdeploy我正在尝试将我的应用程序从Tomcat迁移到Weblogic12.2.1.3.0。我能够毫无错误地部署应用程序,但我遇到了与持久性提供程序相关的运行时错误。这是堆栈跟踪:javax.validation.ValidationException:CalltoTraversableResolver.isReachable()threwanexceptionatorg.…
    2025-04-161
  • Resteasy Content-Type 默认值

    ResteasyContent-Typedefaults我正在使用Resteasy编写一个可以返回JSON和XML的应用程序,但可以选择默认为XML。这是我的方法:@GET@Path("/content")@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})publicStringcontentListRequestXm…
    2025-04-161
  • 代码不会停止运行,在 Java 中

    thecodedoesn'tstoprunning,inJava我正在用Java解决项目Euler中的问题10,即"Thesumoftheprimesbelow10is2+3+5+7=17.Findthesumofalltheprimesbelowtwomillion."我的代码是packageprojecteuler_1;importjava.math.BigInteger;importjava…
    2025-04-161
  • Out of memory java heap space

    Outofmemoryjavaheapspace我正在尝试将大量文件从服务器发送到多个客户端。当我尝试发送大小为700mb的文件时,它显示了"OutOfMemoryjavaheapspace"错误。我正在使用Netbeans7.1.2版本。我还在属性中尝试了VMoption。但仍然发生同样的错误。我认为阅读整个文件存在一些问题。下面的代码最多可用于300mb。请给我一些建议。提前致谢publicc…
    2025-04-161
  • Log4j 记录到共享日志文件

    Log4jLoggingtoaSharedLogFile有没有办法将log4j日志记录事件写入也被其他应用程序写入的日志文件。其他应用程序可以是非Java应用程序。有什么缺点?锁定问题?格式化?Log4j有一个SocketAppender,它将向服务发送事件,您可以自己实现或使用与Log4j捆绑的简单实现。它还支持syslogd和Windows事件日志,这对于尝试将日志输出与来自非Java应用程序…
    2025-04-161