通过函数模板传递时,无法从0构造指针
Cannot construct pointer from 0 when passed through a function template
假设我有一个任意类型:struct Bar {};
。我想从0构造一个Bar*
,我可以显式地这样做:
Bar* b = 0;
我甚至可以通过函数调用隐式地完成:
void foo(Bar* b) { Bar* x = b; }
foo(0);
但当我通过函数模板:时,这种能力就消失了
template <typename T>
void foo(T t) {
Bar* x = t;
}
foo(0); // error: invalid conversion from ‘int’ to ‘Bar*’
为什么不呢?另外两种不再适用的配方有什么特别之处?
0
的指针与0
(即int
文字)到Bar*
的类型推导不同。因此出现了错误。
为了符合c++11标准,请使用nullptr
关键字而不是普通的0
文字来取消对类型的模糊化
还要注意的是,对于c++11之前的标准实现,使用好的旧NULL
宏可能比普通的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
指针!
零是特殊的。零作为一个常量可以分配给一个指针来表示空指针。但是,在没有强制转换的情况下,通常不能将int赋值给指针。
相关文章:
- 匹配函数指针作为模板参数?
- 函数指针作为模板参数
- 将函数指针数组中的函数指针作为模板参数传递
- 使用带有 lambda 函数指针的模板
- C++常规指针函数或模板
- 通过指针调用模板类成员函数 [为什么这是有效的 c++]?
- 使用类指针重载C++命名空间函数模板专用化替代方法?
- 函数指针作为模板参数
- 在C++17中,为什么类模板和函数模板的指针类型推导明显不一致
- 如何通过指针将模板成员函数传递给另一个成员函数
- C++成员函数模板将成员函数指针作为模板参数
- 将指向成员的指针函数传递到模板中
- 带有此指针的模板类多重继承构造函数不起作用?
- 使用通用函数指针参数化函数模板的简洁方法
- 带有指向成员函数的指针的模板 =VC++ 2017 和 gcc 5.1 的>不同的错误消息
- 将常量添加到函数模板指针参数
- 为成员函数定义代理,该代理将成员函数指针作为模板参数
- 函数指针的模板参数推导(g++ & ICC vs Clang++ & VC++)
- 使用原始指针作为参数的函数模板推导
- 'Incomplete type' 为标准::函数声明指向成员的指针函数模板参数时出错