为什么 auto 关键字不能与指向函数的指针的初始化列表一起使用?
Why isn't auto keyword working with initialization list of pointers to functions?
我最近一直在试用C++11,特别是auto
关键字,结果证明它非常有趣和有用。
然而,由于某些原因,它不适用于函数指针的初始化列表。首先,我在书中寻找答案,发现"auto关键字只适用于单个初始化值,而不适用于初始化列表",但当我尝试过时:
auto foo = { "bar", "bar", "bar" };
std::cout << *(foo.begin());
它运行得很好,但当我尝试这样做时:
// bar is a simple void bar() function
auto foo = { bar, bar, bar };
Visual Studio编译器吐唾沫:
error C1001: An internal error has occurred in the compiler.
如果有效:
auto foo = bar;
因此,我决定在互联网上进行一次小旅行,以获得更多关于std::initializer_list
的信息,在那里我了解到它实际上与std::vector
非常相似。那么,我为什么不试试呢?
std::vector<void (*)()> foo = { bar, bar, bar };
(*foo.begin())();
工作完美无瑕。从那以后,我陷入了困境,我不知道为什么auto
关键字不能用于函数指针的初始化列表。为什么它会出现问题,特别是在指向函数的指针方面,C++标准对它最重要的说明是什么?
编辑:
我也尝试过使用GCC和yup做同样的事情,它很有效,所以看起来你们是对的,MSVC编译器有一个错误。我想我需要等到他们修复它,同时我会简单地使用GCC。
这似乎只是MS VC++的一个bug。至少这个代码
auto foo = { bar, bar, bar };
其中bar是一些用GCC成功编译的函数。
消息
error C1001: An internal error has occurred in the compiler.
显示这是编译器中的一个错误。我刚刚在gcc 4.7.2中尝试过,下面的代码运行良好,并打印出"Hello!":
#include <iostream>
void bar()
{
std::cout << "Hello!n";
}
int main()
{
auto foo = { bar, bar, bar };
(*(foo.begin()))(); // prints "Hello!"
}
您的代码应该可以工作,这是一个VC++错误。然而,在表达式中
auto foo = { bar, bar, bar };
foo
的元素不是指向函数的指针,而是指向函数的引用。如果您希望foo
包含指向函数的指针,则需要将其创建为:
auto foo = { &bar, &bar, &bar };
这个例子证明了这种差异:
#include <type_traits>
void bar() {}
template<typename T>
using remove_ref_and_const = typename std::remove_const<
typename std::remove_reference<T>::type
>::type;
int main()
{
static_assert(std::is_same<
remove_ref_and_const<decltype(bar)>,
void()>::value, "Oops1");
static_assert(std::is_same<
remove_ref_and_const<decltype(&bar)>,
void(*)()>::value, "Oops2");
}
现场演示
编辑:上面的答案并不完全正确。尽管bar
和&bar
之间存在差异,但当您将它们添加到初始值设定项列表中时,前者也会衰减为指向函数的指针。下面的几个static_assert
演示了这一点。
auto foo1 = { bar, bar, bar };
auto foo2 = { &bar, &bar, &bar };
static_assert(std::is_same<
remove_ref_and_const<decltype(*foo1.begin())>,
void(*)()>::value, "Oops3");
static_assert(std::is_same<
remove_ref_and_const<decltype(*foo2.begin())>,
void(*)()>::value, "Oops4");
现场演示
- 分段错误 - 读取初始化指针的数组
- 初始化指针的常量向量
- 初始化指针或引用成员变量以指向另一个成员
- C++初始化指针/引用/复制细微差别
- 使用无效指针初始化指针声明符的行为是否未定义?
- 在一行中初始化指针(新uint8_t[高度*宽度*3])
- 如何使用可变模板初始化指针?
- 初始化指针时出现写入访问冲突
- C 错误,带有卷曲括号的字面初始化指针
- 重新初始化指针是一种不好的做法吗?
- 初始化指针?C
- 初始化指针向量的向量
- 如何在类函数中正确初始化指针
- C++初始化指针会使应用程序随机崩溃
- 初始化指针结构 - 内存中的外观
- 如何使用struct构造函数在结构中初始化指针阵列
- 在一行中声明并初始化指针到类实例
- 分配数组与初始化指针
- QT 中的非初始化指针
- 使用地址值初始化指针