Search code examples
c++c++builder-10.4-sydney

Please, help me understand this "pack expansion does not contain any unexpanded parameter packs" compiler error


template<typename ...>
bool foo(std::tuple<std::string,float> bar...)
{
    std::vector<std::tuple<std::string,float>> barList(bar...);

    // ...
}

This does not seem to generate any syntax error. There is no error indicator at that line in the editor, but the compiler stops with

[bcc32c Error] Foo.cpp(117): pack expansion does not contain any unexpanded parameter packs

I tried to read online, but all examples I find either seem incomplete, or are not clear to me.

A simple answer to why this does not compile would be appreciated.


Solution

  • Your syntax is wrong. Your function is equivalent with:

    bool foo(int bar...)
    {
        std::vector<int> barList(bar...);
    
        // ...
    }
    

    Notice there is no variadic templates at all, and there is nothing to unpack - instead, you have created a C-style variadic function.

    One easiest way to change your function would be:

    template<typename... Args>
    bool foo(Args... bar)
    {
        std::vector<std::tuple<std::string,float>> barList({bar...});
    
        // ...
    }
    

    This is not ideal, as it makes your template function quite greedy - it will gladly consume any arguments, not just tuples of strings and floats.

    We can spice it up by using C++20 concepts:

    template<class T>
    concept Tuple = std::is_same_v<T, std::tuple<std::string, float>>;
    
    template<Tuple... T>
    bool foo(T... bar)
    {
        std::vector<std::tuple<std::string, float>> barList({bar...});
    
        // ...
        return true;
    }
    

    This allows usage like that:

    foo(std::tuple<std::string, float>{"ddd", 20}, std::tuple<std::string, float>{"ddd", 20});
    

    But not like that:

    foo(10, 20, nullptr);