C++ 我需要宏还是可以用模板实现
我希望用模板重构一些代码。我知道我可以用宏轻松地完成,但我更喜欢模板/内联lambda。它在功能上应该是等效的 代码如下:C++ 我需要宏还是可以用模板实现,c++,templates,c++11,macros,C++,Templates,C++11,Macros,我希望用模板重构一些代码。我知道我可以用宏轻松地完成,但我更喜欢模板/内联lambda。它在功能上应该是等效的 代码如下: static const Name AssetName = Name(TEXT("AssetName")); AssetPtr = (AssetPtrType*)GetAssetFromName(AssetName); if (!AssetPtr) return false; 静态常量等非常重要,因为此函数可以调用上千次,并且有许多资产要加载,因此需要进行优化
static const Name AssetName = Name(TEXT("AssetName"));
AssetPtr = (AssetPtrType*)GetAssetFromName(AssetName);
if (!AssetPtr)
return false;
静态常量等非常重要,因为此函数可以调用上千次,并且有许多资产要加载,因此需要进行优化。那么我该如何概括呢
#define LOAD_ASSET(AssetName, AssetPtr, AssetPtrType)
LOAD_ASSET(CoolTexture, this->CoolTexture, Image)
LOAD_ASSET(CoolModel, this->CoolModel, Mesh)
我可以使用最新的MSVC支持的任何C++11/14/etc函数。忽略是否应该这样做的问题,我认为(几乎)直译应该是:
template<size_t CNT, class T>
void loadAsset(const char* AssetName, T*& AssetPtr) {
static const Name an = Name(TEXT(AssetName));
AssetPtr = (T*)GetAssetFromName(an);
if (!AssetPtr) {
throw SomeSensibleException{};
}
}
int foo()
{
try {
loadAsset<0>("CoolTexture", this->CoolTexture);
loadAsset<1>("CoolModel", this->CoolModel);
} catch (SomeSensibleException&) {
return false
}
}
模板
void loadAsset(常量字符*AssetName、T*&AssetPtr){
静态常量名称an=Name(文本(AssetName));
AssetPtr=(T*)GetAssetFromName(an);
如果(!AssetPtr){
抛出一些敏感的异常{};
}
}
int foo()
{
试一试{
loadAsset(“CoolTexture”,此->CoolTexture);
loadAsset(“CoolModel”,此->CoolModel);
}捕获(某些敏感异常&){
返回错误
}
}
问题在于,您需要为每个资产(而不仅仅是每个资产类型)分别实例化一个模板函数。否则,多个资产应该共享同一个静态变量。现在从我的头脑中,我想不出一种非宏的方式来同时使用字符串文字作为模板和函数参数,这就是为什么要增加计数器
如果foo在源文件中,您可能可以用\uuuu COUNTER\uuuu
替换手动计数,尽管我不确定它是否具有可移植语义。如果foo被编译成多个翻译单元,这将是危险的,因为\uuuuu COUNTER\uuuu
可能有不同的值,并且会违反odr
如果您确实验证过,使用局部静态变量可以显著提高原始代码的性能,我宁愿使用宏版本,至少在使用模板版本之前对其进行分析。忽略是否应该这样做的问题,我认为(几乎)直译为:
template<size_t CNT, class T>
void loadAsset(const char* AssetName, T*& AssetPtr) {
static const Name an = Name(TEXT(AssetName));
AssetPtr = (T*)GetAssetFromName(an);
if (!AssetPtr) {
throw SomeSensibleException{};
}
}
int foo()
{
try {
loadAsset<0>("CoolTexture", this->CoolTexture);
loadAsset<1>("CoolModel", this->CoolModel);
} catch (SomeSensibleException&) {
return false
}
}
模板
void loadAsset(常量字符*AssetName、T*&AssetPtr){
静态常量名称an=Name(文本(AssetName));
AssetPtr=(T*)GetAssetFromName(an);
如果(!AssetPtr){
抛出一些敏感的异常{};
}
}
int foo()
{
试一试{
loadAsset(“CoolTexture”,此->CoolTexture);
loadAsset(“CoolModel”,此->CoolModel);
}捕获(某些敏感异常&){
返回错误
}
}
问题在于,您需要为每个资产(而不仅仅是每个资产类型)分别实例化一个模板函数。否则,多个资产应该共享同一个静态变量。现在从我的头脑中,我想不出一种非宏的方式来同时使用字符串文字作为模板和函数参数,这就是为什么要增加计数器
如果foo在源文件中,您可能可以用\uuuu COUNTER\uuuu
替换手动计数,尽管我不确定它是否具有可移植语义。如果foo被编译成多个翻译单元,这将是危险的,因为\uuuuu COUNTER\uuuu
可能有不同的值,并且会违反odr
如果您确实验证过,使用局部静态变量可以显著提高原始代码的性能,那么我宁愿坚持使用宏版本,至少在使用模板版本之前对其进行分析。请告诉我重构此代码的优势是什么?PS:我认为宏是一种错误的方法。只是想澄清一下,变量
AssetName
是否对所有不同的资产都有不同的名称?另外,您说您将加载数千个资产,但您是在程序运行时执行此操作,还是仅在启动时执行此操作?你会重新加载资产吗?是否将AssetName
变量重用到加载之外的任何其他地方?静态常量
部分对我来说似乎是过早的选择,你有没有进行基准测试和衡量,它是一个主要的瓶颈?对我来说,你的问题仍然不清楚。您是否希望用其他东西(可能是您的第一个代码段)替换LOAD_ASSET
。你是在问是使用宏还是模板?您将如何使用此实用程序?我发现令人惊讶的是,创建名称似乎是一项非常昂贵的操作,您希望使用静态变量对其进行优化,但实际加载资产却不是。什么是TEXT
和name
?请告诉我重构此代码的优点?PS:我认为宏是一种错误的方法。只是想澄清一下,变量AssetName
是否对所有不同的资产都有不同的名称?另外,您说您将加载数千个资产,但您是在程序运行时执行此操作,还是仅在启动时执行此操作?你会重新加载资产吗?是否将AssetName
变量重用到加载之外的任何其他地方?静态常量
部分对我来说似乎是过早的选择,你有没有进行基准测试和衡量,它是一个主要的瓶颈?对我来说,你的问题仍然不清楚。您是否希望用其他东西(可能是您的第一个代码段)替换LOAD_ASSET
。你是在问是使用宏还是模板?您将如何使用此实用程序?我发现令人惊讶的是,创建名称似乎是一项非常昂贵的操作,您希望使用静态变量对其进行优化,但实际加载资产却并非如此。什么是TEXT
和name
?您可以澄清CNT
的需要。不明显的是,静态
名称起作用。您可以澄清CNT
的需要。不明显的是,静态
名称起作用了。