5

以下代码不能使用clang++ 3.8.0g++ 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*{}编译器在此处以正确方式解释的方法(typedefing ofint*是其中一种方式)?

4

3 回答 3

8

你有几个选择。

您已经发现的一个是类型别名:

using PInt = int*;
PInt a = PInt{};

另一个是避免完全没有意义的复制初始化:

int* a{};
PInt a{};

最好不要在这个傻瓜的差事上浪费时间,并以清晰的方式初始化您的指针:

int* a = nullptr;

当然,如果您的问题真的是关于创建用于表达式的临时而不是完整声明(不清楚),那对您没有帮助;但是你有一个简单的 C 风格(int*)nullptr可以玩。

不过,简短的回答是,您不能“强制”编译器忽略 C++ 的语法,而是使用其他一些语法。

于 2017-04-14T16:35:14.073 回答
0

第一个想法是使用复合文字,例如:

int* a = (int*){};

但正如建议的那样,它是 gcc 和 clang c++ 编译器中作为扩展存在的 C99 功能。

更好的方法可能是decltype(variable_name)用作要统一初始化的类型,例如:

int* a = decltype(a){};

这个成功地避免了typedeforusing子句并完成了工作。

[现场演示]

于 2017-04-14T16:41:48.110 回答
0
template <typename T>
using identity = T;

int main()
{
    int* c = identity<int*>{};
    (void)c;
}
于 2017-04-15T10:45:30.087 回答