Search code examples
c++templatesclass-names

Can class name be referenced implicitly at compile-time?


Is there a way to implicitly reference a class' name at compile-time?

Specifically, if I want to declare an instance of template class A using class B from within the scope of class B, is there a way to avoid explicit reference to "B" in the syntax to declare the class A instance?

To better-illustrate with an example:

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

What I've tried:
Read Is there a __CLASS__ macro in C++?, so I'm aware there's no __CLASS__ (pseudo-equivalent to __FUNCTION__) preprocessor macro. Some of the solutions to that post extract the class name from __PRETTY_FUNCTION__ - but that is a runtime solution not applicable to this situation.

I've read conflicting information on StackOverflow about whether typeid(T) is run time or compile time; either way, A<typeid(*this).name()> a_; doesn't compile, and looks wrong anyhow: there's obviously no this in that context.
By my reading, the text at https://en.cppreference.com/w/cpp/language/typeid makes clear that typeid is runtime, and so not-applicable to this situation.


Solution

  • There is no way to avoid using the type name in LongClassName::privFunc and A<LongClassName> a_;.

    That said, you can still make your life easier. You can make an alias for LongClassName that you can use it it's place. Adding

    using LCN = LongClassName;
    

    will let you use LCN in place of LongClassName