假设我有一个任意类型:struct Bar {};
。我想从0构造一个Bar*
,我可以明确地做到这一点:
Bar* b = 0;
我甚至可以通过函数调用隐式地执行它:
void foo(Bar* b) { Bar* x = b; }
foo(0);
但是当我通过函数模板传递0时,该能力消失了:
template <typename T>
void foo(T t) {
Bar* x = t;
}
foo(0); // error: invalid conversion from ‘int’ to ‘Bar*’
为什么不呢?另外两种不再适用的配方有什么特别之处?
答案 0 :(得分:6)
初始化指向0
的指针与0
(即int
字面值)到Bar*
的类型推导不同。因此错误。
为了符合c++11标准,请使用nullptr
关键字而不是普通0
字面值来解除类型。<
另请注意,使用旧的NULL
宏的pre-c ++ 11标准实现可能比普通0
文字更好,因为NULL
通常会扩展为(void*)0
使用模板和指向模板参数类型的指针时会有所不同。
对于(略微错误的)模板函数定义
template <typename T>
void foo(T* t) {
// ^^ Note!
T* x = t;
// ^ Note!
}
以下代码应该用C ++ 11编译为
foo(nullptr); // C++11
和Pre C ++ 11
foo((void*)0); // NULL didn't work for IDEONE GCC 4.8 and including
// <cstddef>. I'd expect it to expand to (void*)0, but
// it seems expanding to (int*)0 ?!?
<强>更新强>
如果要确保传递的指针类型符合某些基类指针类型,则需要显式转换:
template <typename T>
void foo(T* t) {
Bar* x = static_cast<Bar*>(t);
}
但是你必须将具体的指针类型传递给函数:
class Derived : public Bar
{
// Blah!
};
Derived* x = 0;
foo(derived);
static_cast
不适用于void
指针!
答案 1 :(得分:3)
零很特别。可以将零作为常量分配给表示空指针的指针。但是你不能在没有强制转换的情况下将int赋值给一般的指针。