0

Consider the following code:

#include<queue>
#include<type_traits>

int main() {
    std::queue<int> q;
    auto p{q};
    static_assert(std::is_same<decltype(q), decltype(p)>::value, "fail");
}

It compiles fine with GCC 5.1.0 (see here) and clang 3.8.0 (see here), but it doesn't with GCC 4.9.0 (see here).
From a further analysis, it seems to be due to the fact that the type of p is deduced as std::initializer_list.
As an example, it works if one substitutes the line:

auto p{q};

With the line:

decltype(q) p{q};

I'm not sure which one is right (even though GCC 5.1.0 works according with my expectations) and that's why I've asked here.
Is it right to expect the type of p to be std::queue<int>?

skypjack
  • 49,335
  • 19
  • 95
  • 187
  • This is exceptional situation. Mayers wrote about this in the "Effective modern C++" for C++11/14. This is due to a special type deduction rule for auto. When the initializer for an auto-declared variable is enclosed in braces, the deduced type is a std::initial izer_list. If such a type can’t be deduced (e.g., because the values in the braced ini‐ tializer are of different types) – arturx64 Apr 07 '16 at 13:06
  • auto is c++11 feature and as far as I know it's fully supported in gcc only from 5.1 – Peregrin Apr 07 '16 at 14:32

2 Answers2

1

This is a known defect in the standard that auto deduces {} as std::initializer_list. There is a proposed change to fix this defect.

Newer gcc and clang implement the proposed resolution, whereas gcc-4.9 does not.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
0

No. {q} evaluates to std::initializer_list. There's nothing to tell the compiler you might want something else so auto uses that one.

Also decltype(q) is not the same as decltype({q});

Sorin
  • 11,863
  • 22
  • 26