【问题标题】:Hiding constexpr variables隐藏 constexpr 变量
【发布时间】:2018-11-26 09:59:31
【问题描述】:

我有一些constexpr 函数可以让我简单地改变我的算法的行为。这些函数从一些变量中推断出它们的返回值。一个最小的示例如下所示:

// A.h
constexpr std::array<int,3> a = {1,2,3};

constexpr int Foo() {return a[1]*a[2];}
constexpr int Bar() {return a[3];}

现在,所有这些都在头文件中实现,因为我希望内联方法。但是,我不想将a 暴露给包括A.h 在内的任何人。我怎样才能做到这一点?

【问题讨论】:

  • 正如constexpr 暗示inlineinline 要求每个调用者都遇到过该函数的定义,而这些定义需要知道a,我想你已经敬酒了。 detail 命名空间是否足够?
  • 是的,不是的。我知道detail 命名空间概念,但希望会有更复杂的东西。无论如何,谢谢!
  • 您也可以将a 设为类的私有成员,然后将公共内容(Foo()Bar())设为friend 函数。 a 仍将存在于每个人看到的源代码中,但编译器会更好地阻止不明智的直接访问。
  • 我认为您可以为此使用 extern,请参阅 stackoverflow.com/questions/30208685/…,但它会抵消内联优化器。

标签: c++ c++17 constexpr


【解决方案1】:

在模块前的 C++ 世界中,您的选择是有限的。必须公开您不希望用户看到的事物的定义的常见习惯用法是创建一个所谓的“详细信息”命名空间。这是一个命名空间,通常命名为detail 或类似的名称,其中包含所有界面的内容。按照惯例,用户不应访问该命名空间中的内容。

您可以将 a 设为私有,static constexpr 某个类的成员。这将更有效地阻止用户访问它。但它的缺点是你必须friend每个使用它的函数。

【讨论】:

  • 我的想法也差不多。我在这里要求确保我没有忽略某些东西。谢谢。
【解决方案2】:

如果您的函数不是该类的成员,您可以:

  • public_a.h(a.cpp 用户可见)
  • private_a.h(包含在 a.cpp 中,位于您的源代码中)
  • a.cpp

并将函数放置在正确的位置。你只需要确保 a.cpp 可以被某人使用#包括 public_a.h。

您还可以有一个公开可见的基类来提供您想要的 API,并将自定义隐藏在派生类中,但这会增加额外的复杂性,例如工厂方法。

【讨论】:

  • 如果我没记错的话,C++17 不允许 virtual 函数成为 constexpr (我相信这是 C++20 的特性)。所以整个基类/派生类的东西都不是初学者。此外,所有 OP 的东西都是 constexpr必须公开它们的定义,因此将它们放在 .cpp 文件中也是不可行的。
  • 我的阅读是 OP 必须至少有一些代码没有内联在头文件中。否则,如果剩下的都是,不暴露一些代码有什么意义?
  • 这样人们就不会认为实现细节是接口的一部分。 FooBar 是稳定的 API 用户界面。 a 是一个实现细节,因此可能会发生变化。因此,您不应该直接看它。通常这样做的方式是标头仅包含接口的内容。但是内联、constexpr 和模板使这变得困难。这也是 C++ 需要模块的另一个原因。
猜你喜欢
  • 2012-11-05
  • 2015-05-04
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
相关资源
最近更新 更多