【问题标题】:C++ type of enclosing class in static member function静态成员函数中封闭类的 C++ 类型
【发布时间】:2014-01-15 16:45:01
【问题描述】:

我认为这是完全不可能的,但如果。是否有可能在任何版本的 C++ 中以某种方式在静态成员函数中获取封闭类的类型?

class Impossible {
public:
    static void Fun()
    {
        typedef Impossible EnclosingClass;

        // now do something with EnclosingClass ...
    }
}

有没有办法在函数中不写类名的情况下获取封闭类的类型(在这种情况下为Impossible)?

我之所以这样做是为了避免在函数中重复类名。如果发生这种情况,很容易导致难以找到复制粘贴错误:

class SomeOther { // another class, with the same interface as Impossible
public:
    static void Fun()
    {
        typedef Impossible EnclosingClass;
        // whoops, copy-pasted, forgot to change "Impossible" to "SomeOther"

        // now do something with EnclosingClass ...
    }
}

有没有防止这种事情发生的好方法?我可以想象触摸在封闭类中声明为私有的东西,但这将迫使我编写额外的代码(因为我当前的设计不包含任何固有的私有成员,所有都是公共的)。

【问题讨论】:

  • +1 告诉我们为什么你想要这个而无需被戳和刺激。
  • @jbgs 我不确定我是否理解这有什么帮助。你的意思是让整个 Fun() 成为一个模板?这将使我每次调用都重复类名两次,而不仅仅是每次声明。请注意,尽管 Run() 在大多数情况下都是相同的(因此容易出现复制粘贴错误),但在某些情况下可能会有所不同,所以我认为将其设为全局静态函数并不是一个好主意(但又一次,可以使用该函数的模板特化)。这就是你的想法吗?
  • @JohnDibling:令我惊讶的是,这里没有长期合作者开始“但它真的那么重要吗?” cmets 系列。提出类似的问题就像穿过一堵砖墙,你不仅要解释为什么要这样做,还必须在人们帮助你之前说服他们为什么他们想要这样做.否则他们只会花几个小时告诉你为什么你错了,你在寻找什么是完全不必要的,更不用说你告诉他们为什么会想要它。为一个好问题 +1。
  • 我想知道你为什么要复制粘贴,但也许我的水平太高了。
  • @rubenvb 这是一个出现在图框架中的问题,其中大多数边/顶点类非常相似,有细微的差别。实现本身非常小,只有几行代码,因此在使用通用实现方面没有太多工作要做,无论是基类还是实用程序函数。所以不幸的是,东西被复制/粘贴了。另见stackoverflow.com/questions/21143835/…

标签: c++ types static-methods


【解决方案1】:

问题在于 C++ 缺少 self 关键字。

我通常写:

struct Foo
{
   typedef Foo self;

   static void bar()
   {
      self* ptr = nullptr;
   }
};

我知道你仍然必须确保typedef 是正确的,但至少这样你可以将它放在你会注意到它的类型定义的顶部。

不过,you can make this entirely autonomous.

【讨论】:

  • decltype 太糟糕了,那将是最酷的(非常感谢您的尝试)。但听到有人说“我通常写作”,我仍然感到安慰,我有点担心我正在努力实现愚蠢的事情。
  • 您不会真的认为使用 this 的表达式(即使是未计算的表达式)可以在静态函数中工作,是吗?
  • @JamesKanze:不,但我想我不妨试一试,以防它在未评估的上下文中得到特殊处理,或其他什么。奇怪的事情发生了。 (顺便说一句,它是在类范围内,而不是在静态成员函数中。)
  • 我认为this_typebase_type 很符合C++ 命名约定,而Boost 也遵循这个约定。
【解决方案2】:

C++ 没有获取当前类名、命名空间等的任何功能。在 C++11 中,您可以获取变量的类型,但首先需要变量。在这种情况下,你没有任何东西可以开始。

【讨论】:

    【解决方案3】:

    我喜欢尝试引入一些可以在不相关的类中引用的通用名称的想法;为了可维护性。

    我的第一种方法很简单:在封闭类中提供typedef。在每个不相关的类中为 typedef 赋予相同的名称。

    class Impossible {
    public:
        typedef Impossible Enclosing;
        static void Fun()
        {   
            Enclosing* theObject = 0;
        }   
    };
    

    这样做也会产生效果——我称之为好处——在你没有提供typedef的新的不相关的类中编译失败。

    【讨论】:

    • 哇,好优雅。不知道我怎么没看到。谢谢。
    猜你喜欢
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多