【问题标题】:Declaring two or more types for a public class variable in c++在 C++ 中为公共类变量声明两种或多种类型
【发布时间】:2020-07-13 12:03:34
【问题描述】:

注意:我使用的是 C++11


假设我有一个类 foo 和公共变量 bar,它可以是浮点数或整数。 bar 的类型在分配时确定,如下所示:

foo object_name;
object_name.weight() = value

如果value 是一个整数,那么object_name.weight() 是一个整数,如果value 是一个浮点数,那么object_name.weight() 是一个浮点数。

一种可能性是有两个类foo_ifoo_fbar 的类型分别为 int 和 float;但这很不方便,尤其是foo_ifoo_f 基本上是彼此的克隆,只有它们之间的类型不同。

有没有办法在单个类的范围内将bar 的类型指定为intfloat

【问题讨论】:

  • 如果你会使用 C++17 或更高版本,你可以使用std::variant
  • @RSahu 我只有 C++14 及更早版本。到目前为止,我一直在使用 C++11。
  • 我想到的最简单的方法是在 bar 类型上模板类 foo,即 template<typename TBar> class foo { public: TBar bar; }; 。这样,您只需编写一次类主体,然后可以使用typedef foo<int> foo_i;typedef foo<float> foo_f; 来获取您的两个类。
  • 您可能想要滚动您的std::variant 版本。这是一个有意义的抽象,您可以将其用于您的用例。
  • (我会将我的评论扩展为答案。)

标签: c++ class types


【解决方案1】:

为了只编写一次类体,可以在bar的类型上模板类foo,然后使用两个typedef来简化后续使用。示例:

template<typename TBar> class foo { 
    public: TBar bar; 
}; 

typedef foo<int> foo_i; 
typedef foo<float> foo_f;

对于那些刚接触 C++ 的人来说值得注意的是,这种元编程技术实际上会让编译器生成同一个类的两个不同版本,即从生成的二进制文件的角度来看,它相当于用两个编写类体两次bar 的不同类型。

【讨论】:

  • 由于 foo_ifoo_f 没有声明,我可以只使用模板和类声明吗?
  • @R.Burton,简短回答:通常是的。如果上面的代码在一个标头中,并且使用 foo_i 和 foo_f 的客户端代码包含此标头,那么您可以将 foo_ifoo_f 别名视为自动替换为 foo&lt;int&gt;foo&lt;float&gt;。在这种情况下,编译器会为这两种类型推出模板化的类主体,也就是说,您可以认为它们都在同一个标​​头中声明。
  • 您唯一需要担心的是,如果您没有可用于客户端代码的模板化类foo 的完整代码。在这种情况下,您仍然需要前向声明模板类,并使该声明可用。但是,您可以将实现/定义({} 中的所有内容)隐藏在一些不可访问的标头中(或保护它不被 extern template 声明实例化),然后在另一个源文件中显式实例化模板。跨度>
  • 当您编写 C++ 库并试图减少客户端代码编译时间时,后一种方法很有意义。有关更多信息,请参阅template class ...extern template class 上的文档:en.cppreference.com/w/cpp/language/class_template
猜你喜欢
  • 2010-09-18
  • 1970-01-01
  • 2012-06-26
  • 2012-07-15
  • 2011-05-30
  • 1970-01-01
  • 2018-12-16
  • 2014-12-03
  • 1970-01-01
相关资源
最近更新 更多