默认情况下初始化模板中的指针

Default initializing a pointer in a template

本文关键字:指针 情况下 初始化 默认      更新时间:2024-04-28

在下面的代码中,Get()返回模板类型的默认值。我想知道为什么以及如何正确/定义指针类型

#include <iostream>
#include <string>
template <typename ValueType>
inline ValueType Get()
{
return ValueType();   
}
int main()
{
int* IntPtr = Get<int*>();
//int* IntPtr2 = (int*)(); // Invalid
//int* IntPtr3 = (int*){}; // Valid

std::cout << (IntPtr == nullptr ? "nullptr" : "non-nullptr") << std::endl;

std::cin.get();

return 0;
}

当编译器在Get中计算ValueType()时,我本以为它会变成(int*)(),但由于这是无效的,它会被区别对待吗?

当编译器在Get中评估ValueType()时,我本以为它会变成(int*)(),但由于这是无效的,它会被区别对待吗

C++模板虽然与宏非常相似,但不执行文字替换。ValueType仍然是模板范围内的实际类型。因此,是的,return ValueType()将与(int*)()不同,更像using ValueType = int*; return ValueType();

为什么using ValueType = int*; ValueType();工作而(int*)()不工作:

在C++中,形式为T()的表达式(当T是类型时(是值初始化语法,该语法创建类型为T的无名称对象。

值初始化期间,非类类型被初始化为零

问题是(int*)()的形式不是T(),而是(T)()(int*)()被解析为int*的强制转换,但它缺少要强制转换的值。这正是编译器在错误中所说的:

<source>:2:27: error: expected expression
int* IntPtr2 = (int*)();
^

出于同样的原因,using T = int; int x = (T)();也不会编译。

类似地,int* IntPtr3 = (int*){};也是无效的C++(GCC编译它,但例如MSVC不会编译(。

一些可能的解决方案:

  1. typedef是指向某种类型的指针,那么您将能够正常使用T()形式:

    using T = int*;
    T ptr = T();
    
  2. 使用复制列表初始化语法:

    int* ptr = {};
    
  3. 使用直接列表初始化语法:

    int* ptr{};
    

请注意,直接初始化形式int* ptr();也不可用,因为它会受到最麻烦的解析。

相关文章: