簡體   English   中英

為什么auto關鍵字不能與函數指針的初始化列表一起使用?

[英]Why isn't auto keyword working with initialization list of pointers to functions?

我最近一直在嘗試使用C ++ 11,特別是auto關鍵字,結果證明它非常有趣且有用。

但是,由於某種原因,它不適用於函數指針的初始化列表。 首先,我在書中找到了答案,我發現“auto keyword僅適用於單個初始化值而不適用於初始化列表”,但是當我嘗試:

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同樣的東西,是的,它的工作,因此看起來你們是正確的MSVC編譯器有一個錯誤。 我想我需要等到他們修復它,同時我會簡單地使用GCC。

它似乎只是MS VC ++的一個錯誤。 至少這個代碼

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");

現場演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM