【问题标题】:Do I need a macro or can I do this with a template我需要一个宏还是可以用一个模板来做这个
【发布时间】:2016-04-15 06:16:58
【问题描述】:

我希望使用模板重构一些代码。我知道我可以使用宏轻松完成,但更喜欢模板/内联 lambda。它应该在功能上是等效的。

代码如下:

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 函数。

【问题讨论】:

  • 请告诉我重构这段代码的好处? PS:我认为宏将是错误的方式
  • 只是澄清一下,变量AssetName 是否实际上对所有不同的资产都有不同的名称?此外,您说您将加载数千个资产,但您会在程序运行时执行此操作,还是仅在开始时执行此操作?你会重新加载资产吗?您会在加载之外的任何其他地方重用AssetName 变量吗? static const 部分对我来说似乎是过早的优化,你有没有对它进行基准测试并测量它是一个主要瓶颈?
  • 对我来说,你的问题还不清楚。是这样吗,您希望将LOAD_ASSET 替换为其他内容(可能是您的第一个代码sn-p)。你问是否使用宏或模板?你打算如何使用这个实用程序?
  • 令我惊讶的是,创建名称似乎是一项昂贵的操作,以至于您想使用静态变量对其进行优化,但实际上加载资产并非如此。
  • TEXTName 是什么?

标签: c++ templates c++11 macros


【解决方案1】:

忽略你是否应该这样做的问题,我认为(几乎)直译是:

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

问题是您需要为每个资产单独的模板函数实例化,而不仅仅是每个资产类型。否则,多个资产应该共享同一个静态变量。现在,从我的脑海中,我想不出一种非宏方式来使用字符串文字作为模板和函数参数,这就是额外计数器的原因。

如果 foo 在源文件中,您可以将手动计数替换为 __COUNTER__,尽管我不确定它是否具有可移植语义。如果 foo 被编译为 ib 多个翻译单元,这将是危险的,因为 __COUNTER__ 可能具有不同的值,并且您将违反 odr。

如果您已实际验证,使用局部静态变量会显着提高原始代码的性能,我宁愿坚持使用宏版本并至少在使用模板版本之前对其进行分析。

【讨论】:

  • 你可以澄清CNT的需要。 static 名称是否正常工作并不明显。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-24
  • 1970-01-01
  • 2011-02-28
  • 1970-01-01
  • 1970-01-01
  • 2019-09-30
  • 1970-01-01
相关资源
最近更新 更多