5

有没有办法在编译时隐式引用一个类的名称?

具体来说,如果我想在 范围内声明template class Ausing的实例,有没有办法避免在声明实例的语法中显式引用“B”?class Bclass Bclass A

为了更好地说明一个例子:

// main.cpp

#include <iostream>

using namespace std;

template <typename T>
class A
{
public:
  typedef void (T::*TFunc)();

  A( T& t ) : t_( t ) {}

  void callFunc( TFunc tFunc ) { (t_.*tFunc)(); }

private:
  T& t_;
};

class LongClassName
{
public:
  LongClassName() : a_( *this ) {}

  void pubFunc()
  {
    a_.callFunc( &LongClassName::privFunc ); // Can I avoid explicitly using "LongClassName" here?
  }

private:
  void privFunc() { cout << __PRETTY_FUNCTION__ << endl; }

  A<LongClassName> a_; // Can I avoid explicitly using "LongClassName" here?
};

int main( int argc, char* argv[] )
{
  LongClassName().pubFunc();
  return 0;
}

我尝试过的内容:
阅读C++ 中是否有 __CLASS__ 宏?,所以我知道没有__CLASS__(伪等效于__FUNCTION__)预处理器宏。该帖子的一些解决方案从中提取类名__PRETTY_FUNCTION__- 但这是一个不适用于这种情况的运行时解决方案。

我在 StackOverflow 上阅读了关于是运行时间还是编译时间的相互矛盾的 信息;typeid(T)无论哪种方式,都无法编译,并且无论如何看起来都是错误的:在那种情况下A<typeid(*this).name()> a_;显然没有。 根据我的阅读,https: //en.cppreference.com/w/cpp/language/typeid 上的文本清楚地表明这是运行时,因此不适用于这种情况。this
typeid

4

2 回答 2

8

没有办法避免在LongClassName::privFunc和中使用类型名称A<LongClassName> a_;

也就是说,你仍然可以让你的生活更轻松。您可以为它创建一个别名LongClassName,您可以在它的位置使用它。添加

using LCN = LongClassName;

会让你使用LCN代替LongClassName

于 2019-11-07T20:00:49.210 回答
4

您可以使用重新定义的默认参数声明本地别名模板,以避免在第二种情况下使用类名:

template<typename T = LongClassName> using
A = ::A<T>;
A<> a_; // Can I avoid explicitly using "LongClassName" here?

至于 LongClassName 的较短名称,有一个通用约定,即用通用名称声明相应的类型别名。它也将有助于编写复制/移动构造函数等:

class LongClassName
{
public:
  using Self = LongClassName;

  LongClassName() : a_( *this ) {}

  LongClassName(Self const &); // copy constructor

  Self & operator =(Self const &); // copy assignment operator

  void pubFunc()
  {
    a_.callFunc( &Self::privFunc ); // Can I avoid explicitly using "LongClassName" here?
  }

private:
  void privFunc() { cout << __PRETTY_FUNCTION__ << endl; }

  A<Self > a_; // Can I avoid explicitly using "LongClassName" here?
};
于 2019-11-07T20:21:16.443 回答