C++代码与模板方法调用混淆
C++ code confusion with template method call
我使用的程序API的文档缺少所需的信息,所以我试图自己理解如何使用HashMap::FindOrCreateEntry()
方法。
template <typename C> Entry* FindOrCreateEntry(const K& key, C& constructor, Bool& created)
{
/* ... */
Entry* e = (Entry*) _allocator.Alloc(SIZEOF(Entry), C4D_MISC_ALLOC_LOCATION);
if (!e)
{
created = false;
return nullptr;
}
e = constructor.ConstructHashMapEntry(e, key);
/* ... */
return e;
}
我怀疑的部分是第二种同名方法:
struct DefaultEntryConstructor
{
static Entry* ConstructHashMapEntry(void* ptr, const K& key)
{
return new (ptr) Entry(key);
}
};
Entry* FindOrCreateEntry(const K& key, Bool& created)
{
return FindOrCreateEntry(key, *(DefaultEntryConstructor*) nullptr, created); //lint !e413
}
- 为什么没有模板参数传递给
FindOrCreateEntry()
的调用 - 这个电话不应该崩溃吗?它引用了一个
nullptr
!或者至少,这样做应该是危险的?如果我错了,请纠正我
1为什么没有模板参数传递给FindOrCreateEntry()的调用?
因为编译器可以从传递的参数中推断出类型。这里是C = DefaultEntryConstructor
。
2这个电话不应该崩溃吗?它取消引用nullptr!或者至少,这样做应该是危险的?如果我错了,请纠正我。
但DefaultEntryConstructor::ConstructHashMapEntry
是静态,因此在行中
e = constructor.ConstructHashMapEntry(e, key);
构造函数的值从不使用(它是nullptr也无关紧要)-只有指针的type用于解析函数调用。
让我们更详细地看一下这个静态方法调用。当编译器实例化时
e = constructor.ConstructHashMapEntry(e, key);
它知道CCD_ 7的类型CCD_。因此,第一步是确定要调用的函数。根据此功能的类型,呼叫站点可以有四种类型之一:
- 常规非虚拟方法调用:这将生成一个带有隐式
this
参数的常规方法调用,因此它使用constructor
对象引用的值 - 虚拟方法:这将使用某种机制(通常是vtable)在运行时查找函数指针:查找和调用都依赖于对象引用或指针的值
- 静态方法(我们的例子):这将生成一个没有隐式
this
参数的函数调用。这里只使用了对象的类型,并且完全忽略值 - constexpr:对象的运行时值显然不会影响这一点,因此不使用
请注意,虽然将静态方法称为constructor.ConstructHashMapEntry(e, key)
而不是C::ConstructHashMapEntry(e, key)
可能会让人感到困惑,但根据C
的类型,这种形式允许FindOrCreateEntry
同时使用静态和非静态方法。
相关文章:
- C++11:模板方法的模板函数调用无法编译?
- 基于枚举参数调用专用模板方法
- 调用模板参数 constexpr 方法?
- 从非模板类调用专用模板方法
- 是否可以基于类模板的参数调用类方法和全局方法
- 从部分专用模板方法调用模板非静态方法
- 模板方法在C++中相互调用
- 在子类上调用模板化静态方法时获取类的类型名
- 使用 std::async 调用模板函数的正确方法是什么?
- C++ 如何绑定和调用模板化类型方法
- 调用模板方法会导致'operator<'不匹配
- 调用模板布尔函数的最佳方法
- 从专用模板方法调用无专门化的模板方法
- 从另一个模板对象调用模板方法时出现奇怪的编译行为
- 当类型未知时调用模板方法
- 在模板类中调用模板方法
- 数据类型调用模板方法
- 从C++中的另一个模板方法调用模板方法
- 通过指向模板方法的指针调用模板方法
- 从不同的类调用模板方法