Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does C++ allow normal parameters after variadic template parameters?

According to cppreference, the following code is legal:

lock_guard( MutexTypes&... m, std::adopt_lock_t t );

However, the following code cannot be compiled with clang 3.8 (-std=c++1z):

template<typename... Args>
void f(Args&&..., bool)
{}

int main()
{
    f(1, 2, 3, true); // error! see below for details.
}
1>main.cpp(59,2): error : no matching function for call to 'f'
1>          f(1, 2, 3, true);
1>          ^
1>  main.cpp(54,6) :  note: candidate function not viable: requires 1 argument, but 4 were provided
1>  void f(Args&&..., bool)
1>       ^
1>  1 error generated.

Does C++ allow normal parameters after variadic parameters?

like image 953
xmllmx Avatar asked Feb 16 '17 09:02

xmllmx


1 Answers

The function declaration in your code is valid, however deduction does not work properly for such function templates. Note that the following code is well-formed, and instantiates the specialization void f(int, int, int, bool):

template<typename... Args>
void f(Args&&..., bool) {}

int main() {
    f<int, int, int>(1, 2, 3, true);
}

Note that in C++17, MutexTypes... are the template parameters to the class itself:

template <class... MutexTypes> class lock_guard;

so they are known and do not need to be deduced. Note that the constructor with adopt_lock_t cannot be used for C++17 class template argument deduction since the adopt_lock_t argument occurs after the parameter pack. If the committee had been prescient in C++11, they would have put the adopt_lock_t argument at the beginning rather than at the end, but alas, it is too late now.

like image 59
Brian Bi Avatar answered Oct 25 '22 03:10

Brian Bi