C++ 为什么这个可变模板是一个错误?

C++ 为什么这个可变模板是一个错误?,c++,variadic-templates,C++,Variadic Templates,只是想知道为什么这是无效的: #include <iostream> template <std::size_t... Is> void foo(Is&&... args) { std::cout << "foo called with " << sizeof...(Is) << "params\n"; } int main() { foo(1, 2, 3, 4); } #包括 模板 void

只是想知道为什么这是无效的:

#include <iostream>

template <std::size_t... Is>
void foo(Is&&... args) {
    std::cout << "foo called with " << sizeof...(Is) << "params\n"; 
}

int main() {
    foo(1, 2, 3, 4); 
}
#包括
模板
void foo(Is&&…args){

STD::CUT< P>这不是有效的C++,这就是原因。

如果使用模板参数
1、2、3、4
实例化该函数模板,则在将参数替换到模板中后,您将获得签名:

void foo(1&&, 2&&, 3&&, 4&&);
这显然不是一个有效的函数

如果要编写一个函数模板,该模板可以接受任意数量的参数,但必须是正确类型的参数,可以在C++17中这样做:

template<typename T>
  using is_size_t = std::is_same<T, std::size_t>;

template<typename... T>
  std::enable_if_t<std::conjunction<is_size_t<T>...>::value>>
  foo(T&&... args);
模板
使用is_size\u t=std::is_same;
模板
std::如果>
foo(T&…args);
或者(也使用C++17):

模板
std::如果启用,则启用
foo(T&…args);

对于C++14,您需要自己实现
std::conjunction
,例如,使用中的
模板,我最近一直在使用另一种语言,并且完全使用了Monika。为了补充Jonathan的答案,(感谢您的解释和评论)这是如何确保所有参数都是
size\t
类型的(我实际上是想做的):

模板
需要(std::is_same::value&&…)
void foo(Is&&…args){/*…*/}
甚至通过定义一个专门的概念(ma fav)

template <class T> concept bool Integer = std::is_same<T, int>::value; 

template <Integer... Is> void foo(Is&&... args) { /*...*/ }
//        ^^^^^^^awesome
模板概念bool Integer=std::is_same::value;
模板void foo(Is&&…args){/*…*/}
//^^^^^^^^太棒了

Is
不是一个类型。它是一个
size\t
的值。你永远不会写
void foo(1a,2b,3c,…)
,那么你为什么要写
void foo(Is…)
?;)@BaummitAugen,欺骗目标的人看不见right@NathanOliver为什么?你不能推断非类型模板参数,变量与否都没有区别。@BaummitAugen,因为OP甚至没有尝试将值平分。他对类型模板和非类型模板之间的区别感到困惑。我们甚至从
vo开始就没有进行过推断id foo(Is&&…args)<代码>是一个平的编译器错误,不认为C++ 14有折叠表达式吗?“巴里,OOP,我忘记了原始C++ 14是什么;”JoaNaNeWakyy,它不是原始的,它是完全的。概念不是C++语言的一部分。@ Sjordd,我不是说它们是,是吗?延迟它们添加的原因之一是C++社区。对它们进行实验、测试和阐述
template <class... Is>
    requires (std::is_same<Is, int>::value && ...)
void foo(Is&&... args) { /*...*/ }
template <class T> concept bool Integer = std::is_same<T, int>::value; 

template <Integer... Is> void foo(Is&&... args) { /*...*/ }
//        ^^^^^^^awesome