Quantcast
Viewing all articles
Browse latest Browse all 22072

Parameter packs not expanded with '...' c++17 - gcc bug?

Consider the following simple code:

template<typename ...types>class myclass{    using payload_type = mylib::type_traits::type_or_tuple_t<types...>;    template<typename... T>    std::pair<bool, std::optional<payload_type>> try_push(T &&...data)    {        payload_type t;        std::optional<decltype(t)> o;        // this FAILS.        //std::optional<payload_type> res;        return {true, std::move(o)};    }};

Above, the type_or_tuple helper simply converts the variadic pack to either a single type T if it is a single type, or to a tuple of types (tuple<types...>) if it is more than one type.

Gcc (9/10/11) cannot compile this. Particularly, it seems is is unable to properly expand payload_type above, which is of course the type obtained through the type_or_tuple helper:

g++-11 -O2 -std=c++17 -pedantic wtf.cpp -Wall -Wextra -D_POSIX_SOURCE=200809L -lrt -lmylib -lstdc++ -o qwtf.cpp:27:70: error: parameter packs not expanded with ‘...’:   27 |     std::pair<bool, std::optional<payload_type>> try_push(T &&...data)      |                                                                      ^wtf.cpp:27:70: note:         ‘T’

Also notice:

        payload_type t;        std::optional<decltype(t)> o;

compiles. But the commented line will not.

On the other hand, clang has no trouble compiling this.

Is this a bug in gcc or is it incorrect usage of the language? Any ideas as to how to tweak this to get it to compile?

Here is a minimum reproducible example, including the definition of is_type_or_tuple:

#include <iostream>#include <type_traits>#include<optional>#include <tuple>using namespace std;template<typename... types>struct type_or_tuple {    using tup = std::tuple<types...>;    using T = std::conditional_t<(std::tuple_size_v<tup> == 1),                                 std::tuple_element_t<0, tup>,                                 tup>;    using is_tuple = std::conditional_t<(std::tuple_size_v<tup> > 1),                                        std::true_type,                                        std::false_type>;};template<typename... types>using type_or_tuple_t = typename type_or_tuple<types...>::T;//template<typename ...types>class myclass{    using payload_type = type_or_tuple_t<types...>;    template<typename... T>    std::pair<bool, std::optional<payload_type>> try_push(T &&...data)    {        payload_type t;        std::optional<decltype(t)> o;        // WILL NOT COMPILE!        //std::optional<payload_type> res;        return {true, std::move(o)};    }};int main(int, const char **){    myclass<unsigned> c;}

Viewing all articles
Browse latest Browse all 22072

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>