C++variant 类型

wushuai1346 2016-11-01 05:56:53
程序里需要一种类似Qt或者 C# dynamic, object 的类型, 我找了很多类似的项目, 感觉用起来都很麻烦. 自己实现了一版, 希望大家帮我看看这样写的问题在哪里. 然后也希望大家推荐一些类似的开源项目. QVariant就不考虑了 ,谢谢.

#include <memory>
#include <iostream>
#include <map>

class Var
{
public:
Var() : m_val() { }

template<typename T>
Var(T val) { m_val = std::make_shared<T>(val); }

template<typename T>
void setValue(T val) { m_val = std::make_shared<T>(val); }

template<typename T>
T value() { return static_cast<T>(*static_cast<T*>(m_val.get())); }

private:
std::shared_ptr<void> m_val;
};

int _tmain(int argc, _TCHAR* argv[])
{
Var x(1);

std::cout << x.value<int>();

std::map<std::string, Var> voidMap;

voidMap.insert(std::make_pair("1", Var("Hello!")));
voidMap.insert(std::make_pair("2", Var(12)));
voidMap.insert(std::make_pair("3", Var(1.0f)));
Var* val = new Var(true);
voidMap.insert(std::make_pair("4", val));

std::cout << voidMap["1"].value<const char*>();
std::cout << voidMap["2"].value<int>();
std::cout << voidMap["3"].value<float>();
std::cout << voidMap["4"].value<Var*>()->value<bool>();

delete val;

system("pause");

return 0;
}
...全文
867 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
wushuai1346 2016-11-10
  • 打赏
  • 举报
回复
最后使用了 bcp 把 any 模块从 boost 中剥离了出来. 使用boost还是感觉放心些, 虽然我感觉自己实现的Var原理和boost基本一致...
jiqiang01234 2016-11-03
  • 打赏
  • 举报
回复
需要把boost文件夹的路径先在工程里设置,然后 #include "boost/any.hpp"即可
ri_aje 2016-11-03
  • 打赏
  • 举报
回复
引用 5 楼 wushuai1346 的回复:
std::variant 的实现是 C++17的, 我现在用的是VS 2013, 短期内也不会升级这个环境, 所以 17 的东西肯定是排除掉了. _variant_t 这个在 comutil.h 文件内, 如果我理解没有错的话, 应该主要是windows 下的解决方案. 我现在做的东西以后可能要移至到手机上去, 所以和平台结合和紧密的东西, 最好不使用它. boost variant 和 boost any 我原先也看过一些介绍, 只是要使用的话, 要引用N多boost头文件, 我觉得就这么个小功能, 没必要吧? Header Only 的库应该就能解决这个问题了. 以上.
那最简单的就是照着抄了,找个 17 的标准库实现,把 variant 复制出来删掉你不需要的功能,剩下的自己用就行了。
jiqiang01234 2016-11-02
  • 打赏
  • 举报
回复
引用 5 楼 wushuai1346 的回复:
std::variant 的实现是 C++17的, 我现在用的是VS 2013, 短期内也不会升级这个环境, 所以 17 的东西肯定是排除掉了. _variant_t 这个在 comutil.h 文件内, 如果我理解没有错的话, 应该主要是windows 下的解决方案. 我现在做的东西以后可能要移至到手机上去, 所以和平台结合和紧密的东西, 最好不使用它. boost variant 和 boost any 我原先也看过一些介绍, 只是要使用的话, 要引用N多boost头文件, 我觉得就这么个小功能, 没必要吧? Header Only 的库应该就能解决这个问题了. 以上.
boost::variant和boost::any本身就是header only的库。使用的时候只需要包含一个头文件就够了。至于内部怎么实现的,也不需要关心。
wushuai1346 2016-11-02
  • 打赏
  • 举报
回复
毒瘤啊, 我去, 复制粘贴的就不要出来了好么? 你分那么高有毛用? 虚荣心吗? 恶心!
赵4老师 2016-11-02
  • 打赏
  • 举报
回复
请牢记:源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要,重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。 意思是你程序结构看上去再合理,再简洁,也不一定比看上去一团乱麻的程序结构在运行或修改时更不易出错,更方便修改,出错了更容易找到哪里出错和具体出错的原因,更容易改正错误。 试对比 图书馆(对图书的分类够结构化了吧) 和 搜索引擎(可看作是扁平化任何结构数据,仅支持全文检索) 哪个处理信息更方便、更高效。 所以 与其费劲去重构代码让其看上去更简洁、更合理 不如费劲学习grep、sed、awk、……这类全文搜索和批处理编辑的工具。 结构越复杂,越难修改,越难除错。 有时(甚至大多数时候),看上去越合理、越简洁的代码,运行起来性能越差,出错时查找原因越难,找到出错原因后改正越费劲。 程序员要做的不是尽力避免错误,而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误,“快速的失败”远胜过“预防错误”。Fred George 前微软C#编辑器的开发主管Jay Bazuzi列出的一些有助于找到正确方向的问题;他觉得前同事们应该用这些问题来问自己;实际上不管在哪里工作的开发者们都应该经常问问自己这些问题: ◆“要保证这个问题不会再出现,我该怎么做?” ◆“要想少出些Bug,我该怎么做?” ◆“要保证Bug容易被修复,我该怎么做?” ◆“要保持对变化的快速响应,我该怎么做?” ◆“要保证我的软件的运行速度,我该怎么做?” 如果大多数团队都能不时问一下自己,必定会从中得益,因为这些都是真正强而有力的问题。
wushuai1346 2016-11-02
  • 打赏
  • 举报
回复
关于重复造轮子: 如果能用短小精炼的代码实现 boost variant 或者 boost any 的功能, 我觉得也蛮好的, 毕竟 boost 库很大, 因为这个小功能引一堆boost 进来, 似乎是不太妥当吧?
wushuai1346 2016-11-02
  • 打赏
  • 举报
回复
引用 3 楼 60 的回复:
你的这个Var,有很大的问题。 只能存储 void*型的指针,那么指针的创建、和释放有谁去管理。 像你的代码中,手动释放内存,那么你创建Var类型还有什么意义。 使用boost中的variant就可以。
Var这个类型主要是作为存储变量用的, Var 本身不是智能指针, 因为我觉得 std::shared_ptr<Var> 就足够了. 关于指针, 我的观点是谁污染谁治理, 所以 Var 存储的东西, 如果是值类型, 应该会拷贝一份, 如果是 引用类型, 只保留指针, 如果是智能指针, 和值类型一样处理.
wushuai1346 2016-11-02
  • 打赏
  • 举报
回复
std::variant 的实现是 C++17的, 我现在用的是VS 2013, 短期内也不会升级这个环境, 所以 17 的东西肯定是排除掉了. _variant_t 这个在 comutil.h 文件内, 如果我理解没有错的话, 应该主要是windows 下的解决方案. 我现在做的东西以后可能要移至到手机上去, 所以和平台结合和紧密的东西, 最好不使用它. boost variant 和 boost any 我原先也看过一些介绍, 只是要使用的话, 要引用N多boost头文件, 我觉得就这么个小功能, 没必要吧? Header Only 的库应该就能解决这个问题了. 以上.
wushuai1346 2016-11-02
  • 打赏
  • 举报
回复
引用 10 楼 jiqiang01234 的回复:
[quote=引用 5 楼 wushuai1346 的回复:] std::variant 的实现是 C++17的, 我现在用的是VS 2013, 短期内也不会升级这个环境, 所以 17 的东西肯定是排除掉了. _variant_t 这个在 comutil.h 文件内, 如果我理解没有错的话, 应该主要是windows 下的解决方案. 我现在做的东西以后可能要移至到手机上去, 所以和平台结合和紧密的东西, 最好不使用它. boost variant 和 boost any 我原先也看过一些介绍, 只是要使用的话, 要引用N多boost头文件, 我觉得就这么个小功能, 没必要吧? Header Only 的库应该就能解决这个问题了. 以上.
boost::variant和boost::any本身就是header only的库。使用的时候只需要包含一个头文件就够了。至于内部怎么实现的,也不需要关心。[/quote] 刚下载了最新版的 boost 文件, 不管是 any 或者 variant 都不只包含了一个头文件, 我不知道是不是我使用的方式有问题...
// See http://www.boost.org/libs/any for Documentation.

#ifndef BOOST_ANY_INCLUDED
#define BOOST_ANY_INCLUDED

#if defined(_MSC_VER)
# pragma once
#endif

// what:  variant type boost::any
// who:   contributed by Kevlin Henney,
//        with features contributed and bugs found by
//        Antony Polukhin, Ed Brey, Mark Rodgers, 
//        Peter Dimov, and James Curran
// when:  July 2001, April 2013 - May 2013

#include <algorithm>

#include "boost/config.hpp"
#include <boost/type_index.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/throw_exception.hpp>
#include <boost/static_assert.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/mpl/if.hpp>

namespace boost
{
    class any
    {
    public: // structors

        any() BOOST_NOEXCEPT
          : content(0)
        {
        }
上面是 any.hpp 的代码片段, 看起来就不像是只包含一个文件就能使用的啊....
ri_aje 2016-11-02
  • 打赏
  • 举报
回复
别重复造车了,标准库里有 variant,http://en.cppreference.com/w/cpp/utility/variant
060 2016-11-01
  • 打赏
  • 举报
回复
你的这个Var,有很大的问题。 只能存储 void*型的指针,那么指针的创建、和释放有谁去管理。 像你的代码中,手动释放内存,那么你创建Var类型还有什么意义。 使用boost中的variant就可以。
sevancheng 2016-11-01
  • 打赏
  • 举报
回复
已经有_variant_t 了,不要造轮子
Saleayas 2016-11-01
  • 打赏
  • 举报
回复
boost variant

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧