【发布时间】:2013-02-14 03:33:27
【问题描述】:
我有一个简单的模板结构,将字符串与值相关联
template<typename T> struct Field
{
std::string name; T self;
}
我有一个函数,我想接受任何类型的 1 个或多个字段,并且这些字段可能具有不同的类型,所以我使用 std::initializer_list,因为据我所知,C++ 缺少类型可变参数,无法确定可变参数的大小,并且必须至少有一个其他参数才能确定从哪里开始。
问题是我不知道如何告诉它接受可能是不同类型的字段。在 Java 中,我只会使用 foo(Field<?> bar, Field<?>... baz),但 C++ 缺少类型化可变参数和通配符。我唯一的另一个想法是制作类型的参数
std::initializer_list<Field<void*>>,但这似乎是一个糟糕的解决方案……有更好的方法吗?
【问题讨论】:
-
具有不同模板参数的同一模板的实例化是完全不相关的类型。拥有
Field对象后,您打算如何处理它们? C++确实有variadic templates(可用于创建类型安全的可变参数函数)。 -
该函数只是将每个字段存储在一个向量中以备后用,所以我真的不在乎它们的类型是什么。 C++ 可变参数的类型安全性在这里确实是次要问题,因为如果在您发送错误类型时代码崩溃,那么就不要这样做(也就是说,在调用函数之前进行防御性代码并自己检查类型) .我知道 Field
和 Field 实际上并不相关(非(co/contra)方差使得不可能(嗯,不完全是,但由于非类模板参数而变得尴尬)。跨度> -
@MattG 那么所有字段都进入 one 向量?在这种情况下,一个更困难的问题将是该向量的类型应该是什么。
-
“Java”解决方案的 C++ 版本是将
Field定义为struct Field{std::string name; boost::any self;};,但这可能是个坏主意,因为 C++ 允许比这更好的类型安全性。我可能要么让Field模板继承自一个公共基类(具有具有所需接口的虚函数),然后使用value_ptr 来保存它们并传递它们, 或 使@ 987654331@ 是可能的字段类型的boost::variant。 -
嗯。我打算跟踪 std::tuple 中字段的类型,但大声说出来让我意识到这是多么荒谬。
标签: c++ c++11 templates variadic-templates