C++ 是否允许在可变参数模板参数之后使用普通参数?
Does C++ allow normal parameters after variadic template parameters?
根据cppreference,下面的代码是合法的:
lock_guard( MutexTypes&... m, std::adopt_lock_t t );
但是,以下代码不能用 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.
C++是否允许在可变参数之后使用普通参数?
您代码中的函数声明是有效的,但是推导对于此类函数模板无法正常工作。注意下面的代码是well-formed,并且实例化特化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...
是 class 本身的模板参数:
template <class... MutexTypes> class lock_guard;
所以它们是已知的,不需要推导。请注意,带有 adopt_lock_t
的构造函数不能用于 C++17 class 模板参数推导,因为 adopt_lock_t
参数出现在参数包之后。如果委员会在 C++11 中有先见之明,他们会把 adopt_lock_t
参数放在开头而不是结尾,但是现在太晚了。
根据cppreference,下面的代码是合法的:
lock_guard( MutexTypes&... m, std::adopt_lock_t t );
但是,以下代码不能用 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.
C++是否允许在可变参数之后使用普通参数?
您代码中的函数声明是有效的,但是推导对于此类函数模板无法正常工作。注意下面的代码是well-formed,并且实例化特化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...
是 class 本身的模板参数:
template <class... MutexTypes> class lock_guard;
所以它们是已知的,不需要推导。请注意,带有 adopt_lock_t
的构造函数不能用于 C++17 class 模板参数推导,因为 adopt_lock_t
参数出现在参数包之后。如果委员会在 C++11 中有先见之明,他们会把 adopt_lock_t
参数放在开头而不是结尾,但是现在太晚了。