类名可以在编译时隐式引用吗?

问题描述 投票:5回答:2

是否有一种在编译时隐式引用类名的方法?

具体来说,如果我想在template class A范围内使用class B声明class B的实例,是否有一种方法可以避免在声明class A实例的语法中明确引用“ B” ?

为了更好地举例说明:

// 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;
}

我尝试过的:读Is there a __CLASS__ macro in C++?,所以我知道没有__CLASS__(与__FUNCTION__伪等效)预处理器宏。该职位的一些解决方案从__PRETTY_FUNCTION__中提取类名-但这是不适用于这种情况的运行时解决方案。

我已经在StackOverflow上阅读了conflicting是运行时还是编译时的information typeid(T);无论哪种方式,A<typeid(*this).name()> a_;都不会编译,并且无论如何看起来都是错误的:在这种情况下,显然没有this。通过我的阅读,https://en.cppreference.com/w/cpp/language/typeid处的文本清楚地表明typeid是运行时,因此不适用于这种情况。

c++ templates class-names
2个回答
8
投票

无法避免在LongClassName::privFuncA<LongClassName> a_;中使用类型名称。

也就是说,您仍然可以使生活更轻松。您可以为LongClassName设置别名,以使用它的位置。正在添加

using LCN = LongClassName;

将允许您使用LCN代替LongClassName


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?
};
© www.soinside.com 2019 - 2024. All rights reserved.