2017-02-16 71 views
7

Według cppreference następujący kod jest legalny:Czy C++ zezwala na normalne parametry po parametrach szablonu variadic?

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

Jednakże po kod nie może zostać skompilowany z brzękiem 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. 

Czy C++ zezwala na normalne parametry po parametrach wariancji?

+1

Mój kompilator to clang 3.8. gcc 6.2 również się nie powiedzie. – xmllmx

+3

Należy zauważyć, że z przykładem 'lock_guard' jest to konstruktor klasy, więc wszystkie argumenty szablonu są znane wcześniej, zamiast próbować wywnioskować je z argumentów wywołania funkcji. – BoBTFish

+0

To jest C++ 17, a nie C++ 11. – ForEveR

Odpowiedz

9

Deklaracja funkcji w kodzie jest ważna, jednak odliczenie odliczenie nie działa poprawnie dla takich szablonów funkcji. Zauważ, że ten kod jest dobrze wykształcona i instancję specjalizację void f(int, int, int, bool):

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

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

Należy zauważyć, że w C++ 17, MutexTypes... są parametry szablonu do samej klasy:

template <class... MutexTypes> class lock_guard; 

więc są znane i nie trzeba ich wydedukowywać. Zauważ, że konstruktora z adopt_lock_t nie można użyć do odrzucenia argumentu szablonu klasy C++ 17, ponieważ argument adopt_lock_t występuje po pakiecie parametrów. Gdyby komitet był przewidujący w C++ 11, argumenty byłyby umieszczane na początku, a nie na końcu, ale niestety teraz jest już za późno.

+1

Nie jest za późno, patrz http://pl.cppreference.com/w/cpp/thread/scoped_lock/scoped_lock – user2913094