2017-02-16 5 views
7

cppreferenceによれば、次のコードが正当である:C++はバリデーションテンプレートパラメータの後に通常のパラメータを許可しますか?

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

しかし、次のコードは、(-std = C++ 1Z)打ち鳴らす3.8でコンパイルすることができない。

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. 

C++は可変パラメータの後に通常のパラメータを使用できますか?

+1

マイコンパイラは3.8です。 gcc 6.2も失敗します。 – xmllmx

+3

'lock_guard'の例ではクラスコンストラクタなので、すべてのテンプレート引数は関数呼び出しの引数から推測するのではなく、事前に分かっていることに注意してください。 – BoBTFish

+0

C++ 17ではなく、C++ 11です。 – ForEveR

答えて

9

コード内の関数宣言は有効ですが、控除は、そのような関数テンプレートでは正しく機能しません。次のコードは、十分に形成され、専門void f(int, int, int, bool)をインスタンス化するように注意:

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

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

なお、C++ 17、MutexTypes...は、クラス自体のテンプレートパラメータは:それらは

template <class... MutexTypes> class lock_guard; 

推測される必要はありません。 adopt_lock_tのコンストラクタは、パラメータパックの後にadopt_lock_t引数があるので、C++ 17クラスのテンプレート引数の減算に使用できないことに注意してください。委員会がC++ 11で先見的であった場合、彼らは最後ではなく最初にadopt_lock_t引数を入れていただろうが、残念ながら今は遅すぎる。

+1

遅すぎることはありません。http://en.cppreference.com/w/cpp/thread/scoped_lock/scoped_lock – user2913094