【问题标题】:Does C++ allow normal parameters after variadic template parameters?C++ 是否允许在可变参数模板参数之后使用普通参数?
【发布时间】:2017-07-05 07:10:18
【问题描述】:

根据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++ 允许在可变参数后面加上普通参数吗?

【问题讨论】:

  • 我的编译器是clang 3.8。 gcc 6.2 也失败了。
  • 请注意,对于lock_guard 示例,它是一个类构造函数,因此所有模板参数都是预先知道的,而不是试图从函数调用参数中推断出来。
  • 是 C++17,不是 C++11。
  • 确切地说:可变参数是从 C 继承的一个特性,它们必须是最后一个。您在询问 C++11 中引入的参数包。
  • @tad 你能否为 C 特性称为“可变参数”的说法提供证明或参考?

标签: c++ c++11 templates standards variadic-templates


【解决方案1】:

代码中的函数声明是有效的,但是 deduction 不适用于此类函数模板。请注意,以下代码格式正确,并实例化了特化 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 的构造函数不能用于C++17 类模板参数推导,因为adopt_lock_t 参数出现在参数包之后。如果委员会在 C++11 中具有先见之明,他们会将 adopt_lock_t 参数放在开头而不是结尾,但可惜现在为时已晚。

猜你喜欢
  • 2014-07-27
  • 1970-01-01
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
相关资源
最近更新 更多