可以在编译时隐式引用 class 名称吗?
Can class name be referenced implicitly at compile-time?
有没有办法在编译时隐式引用 class' 名称?
具体来说,如果我想在 class B
的范围内使用 class B
声明一个 template class A
的实例,有没有办法避免显式引用 "B" 在声明 class 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;
}
我尝试过的:
阅读 Is there a __CLASS__ macro in C++?,所以我知道没有 __CLASS__
(伪等效于 __FUNCTION__
)预处理器宏。 post 的一些解决方案从 __PRETTY_FUNCTION__
中提取了 class 名称 - 但这是一个 运行 时间解决方案,不适用于这种情况。
我在 Whosebug 上阅读了 conflicting information 关于 typeid(T)
是 运行 时间还是编译时间;无论哪种方式,A<typeid(*this).name()> a_;
都无法编译,而且无论如何看起来都是错误的:在该上下文中显然没有 this
。
根据我的阅读,https://en.cppreference.com/w/cpp/language/typeid 处的文字清楚地表明 typeid
是 运行 时间,因此不适用于这种情况。
无法避免使用 LongClassName::privFunc
和 A<LongClassName> a_;
中的类型名称。
也就是说,您仍然可以让您的生活更轻松。您可以为 LongClassName
创建一个别名,您可以在它的位置使用它。添加
using LCN = LongClassName;
将让您使用 LCN
代替 LongClassName
您可以使用重新定义的默认参数声明本地别名模板,以避免在第二种情况下使用 class 名称:
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?
};
有没有办法在编译时隐式引用 class' 名称?
具体来说,如果我想在 class B
的范围内使用 class B
声明一个 template class A
的实例,有没有办法避免显式引用 "B" 在声明 class 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;
}
我尝试过的:
阅读 Is there a __CLASS__ macro in C++?,所以我知道没有 __CLASS__
(伪等效于 __FUNCTION__
)预处理器宏。 post 的一些解决方案从 __PRETTY_FUNCTION__
中提取了 class 名称 - 但这是一个 运行 时间解决方案,不适用于这种情况。
我在 Whosebug 上阅读了 conflicting information 关于 typeid(T)
是 运行 时间还是编译时间;无论哪种方式,A<typeid(*this).name()> a_;
都无法编译,而且无论如何看起来都是错误的:在该上下文中显然没有 this
。
根据我的阅读,https://en.cppreference.com/w/cpp/language/typeid 处的文字清楚地表明 typeid
是 运行 时间,因此不适用于这种情况。
无法避免使用 LongClassName::privFunc
和 A<LongClassName> a_;
中的类型名称。
也就是说,您仍然可以让您的生活更轻松。您可以为 LongClassName
创建一个别名,您可以在它的位置使用它。添加
using LCN = LongClassName;
将让您使用 LCN
代替 LongClassName
您可以使用重新定义的默认参数声明本地别名模板,以避免在第二种情况下使用 class 名称:
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?
};