int*的统一初始化:怎么强制?
Uniform initialization of int*: how can it be forced?
以下代码无法使用 clang++ 3.8.0 和 g++ 6.3.0 进行编译(编译器标志为 -std=c++11 -Wall -Wextra -Werror -pedantic-errors
):
int main()
{
int* a = int*{}; // doesn't compile
// ^^^^ can't be parsed as a type
(void)a;
using PInt = int*;
PInt b = PInt{}; // compiles successfully
// ^^^^ is parsed as a type
(void)b;
}
这是一种强制编译器在此处以正确方式解释 int*{}
的方法吗(typedef
ing int*
就是其中一种方法)?
你有几个选择。
您已经发现的一个是类型别名:
using PInt = int*;
PInt a = PInt{};
另一个是避免完全无意义的复制初始化:
int* a{};
PInt a{};
最好不要在这种愚蠢的事情上浪费时间,并以清晰的方式初始化您的指针:
int* a = nullptr;
当然,如果您的问题真的关于创建用于表达式的临时对象而不是完整的声明(不清楚);但是你有一个简单的 C 风格 (int*)nullptr
可以玩。
不过,简短的回答是 否 你不能 "force" 编译器忽略 C++ 的语法而使用其他语法。
首先想到的是使用复合文字,例如:
int* a = (int*){};
但正如所建议的那样,它是作为扩展存在于 gcc 和 clang c++ 编译器中的 C99 功能。
更好的方法是使用 decltype(variable_name)
作为统一初始化的类型,例如:
int* a = decltype(a){};
这个成功地避免了 typedef
或 using
子句并完成了工作。
template <typename T>
using identity = T;
int main()
{
int* c = identity<int*>{};
(void)c;
}
以下代码无法使用 clang++ 3.8.0 和 g++ 6.3.0 进行编译(编译器标志为 -std=c++11 -Wall -Wextra -Werror -pedantic-errors
):
int main()
{
int* a = int*{}; // doesn't compile
// ^^^^ can't be parsed as a type
(void)a;
using PInt = int*;
PInt b = PInt{}; // compiles successfully
// ^^^^ is parsed as a type
(void)b;
}
这是一种强制编译器在此处以正确方式解释 int*{}
的方法吗(typedef
ing int*
就是其中一种方法)?
你有几个选择。
您已经发现的一个是类型别名:
using PInt = int*;
PInt a = PInt{};
另一个是避免完全无意义的复制初始化:
int* a{};
PInt a{};
最好不要在这种愚蠢的事情上浪费时间,并以清晰的方式初始化您的指针:
int* a = nullptr;
当然,如果您的问题真的关于创建用于表达式的临时对象而不是完整的声明(不清楚);但是你有一个简单的 C 风格 (int*)nullptr
可以玩。
不过,简短的回答是 否 你不能 "force" 编译器忽略 C++ 的语法而使用其他语法。
首先想到的是使用复合文字,例如:
int* a = (int*){};
但正如所建议的那样,它是作为扩展存在于 gcc 和 clang c++ 编译器中的 C99 功能。
更好的方法是使用 decltype(variable_name)
作为统一初始化的类型,例如:
int* a = decltype(a){};
这个成功地避免了 typedef
或 using
子句并完成了工作。
template <typename T>
using identity = T;
int main()
{
int* c = identity<int*>{};
(void)c;
}