【问题标题】:The need to pass different types in the initialization_list初始化列表中需要传递不同类型
【发布时间】:2020-10-19 23:27:06
【问题描述】:

我正在寻找一种基于模板的方法来在initialization_list(s) 中传递任意数量的参数。

类似:

func({0, 1}, {0, 2.0f}, {0, "boo"}, ...);

func({{0, 1}, {0, 2.0f}, {0, "boo", ...}});

同时,我希望能够检查每个(内部)大括号中第二个参数的类型。也许得到sizeof(T)也许做一些if constexpr(std::is_same<T, ...>::value)匹配。

有可能吗?如果是这样,func() 的定义会是什么样子?

【问题讨论】:

  • 内括号总是有2个元素?
  • std::initializer_list<T>,其中T 是具有重载构造函数的类型?
  • @cigien 是的,基本上是一个索引和一个值
  • 找出类型并不难。你想对func 中的所有这些类型做什么?
  • 我的计划是将任意类型的变量占用的内存复制到一些不透明的内存区域中。需要类型信息才能获取 sizeof(T) 以将大小传递给 memcpy。

标签: c++ templates variadic-templates


【解决方案1】:

fstd::initializer_list<std::pair<std::any, std::any> >:

void f(std::initializer_list<std::pair<std::any, std::any> > il) {
    for (auto it = il.begin(); it != il.end(); ++it) {
        const std::type_info& type1 = it->first.type();
        const std::type_info& type2 = it->second.type();
        if (type1 == typeid(int)) {
            int val1 = std::any_cast<int>(it->first);
        }
        // ...
    }
}

如果您只有几种可能的类型,您可以使用std::variant&lt;int, float, /*e.g.; etc. */&gt; 而不是std::any

【讨论】:

  • Variant 可能是更好的选择。当你有一个函数可以吃掉任意数量的任意类型时,你可能遇到了设计问题。后端消耗所有这些参数的任何东西都将变得复杂并且容易受到错误输入的影响。回到 varargs 函数的旧时代。
  • @user4581301 除了 std::any 如果您尝试使用错误的类型访问它会引发异常,因此如果未显式处理其类型,则最多可以复制其中的对象。不像可变参数函数。
  • 同意。我需要“几乎回到过去”。
猜你喜欢
  • 2016-06-14
  • 2018-09-25
  • 2015-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-04
相关资源
最近更新 更多