Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;已知类型的可变函数模板_C++_C++11_Templates_Variadic Templates_Variadic Functions - Fatal编程技术网

C++ C++;已知类型的可变函数模板

C++ C++;已知类型的可变函数模板,c++,c++11,templates,variadic-templates,variadic-functions,C++,C++11,Templates,Variadic Templates,Variadic Functions,我目前正试图了解一些我可以用可变模板支持做的事情。假设我有一个这样的函数- template <typename ... Args> void foo(Args ... a) { int len = sizeof...(tail); int vals[] = {a...}; /* Rest of function */ } /* Elsewhere */ foo(1, 2, 3, 4); 我尝试过这样做,但是编译器给出了一个错误,关于foo是一个空字段。我

我目前正试图了解一些我可以用可变模板支持做的事情。假设我有一个这样的函数-

template <typename ... Args>
void foo(Args ... a)
{
    int len = sizeof...(tail);
    int vals[] = {a...};
    /* Rest of function */
}

/* Elsewhere */
foo(1, 2, 3, 4);

我尝试过这样做,但是编译器给出了一个错误,关于foo是一个空字段。我知道我也可以通过递归访问包中的参数,但我不确定这是否会解决我的问题-即我希望能够获取相同类型的可变数量的参数。

如果您以前知道这些类型,可以使用函数重载:

#包括
#包括
void foo(标准::初始值设定项\u列表l)
{
用于(自动el:l)
//做点什么
}
void foo(标准::初始值设定项\u列表l)
{
}
void foo(标准::初始值设定项\u列表l)
{
}
int main()
{
foo({1,2,3,4});
foo({1.1f,2.1f,3.1f,4.1f});
foo({“foo”,“bar”,“foo”,“foo”});
返回0;
}
如果使用Visual Studio 2012,则可能需要

编辑:如果仍要使用可变模板,可以执行以下操作:

template <int ... Args>
void foo( )
{
    int len = sizeof...(Args);
    int vals[] = {Args...};
    // ...
}

// And

foo<1, 2, 3, 4>();
模板
void foo()
{
int len=sizeof…(Args);
int vals[]={Args…};
// ...
}
//及
foo();
但您必须记住,它不适用于
float
std::string
,例如:您将以
“float”结束:非类型模板参数的非法类型
float
作为
非类型模板参数是不合法的,这与精度有关,浮点数无法精确表示,引用相同类型的可能性取决于数字的表示方式

我目前正试图了解一些我可以用可变模板支持做的事情

假设您想尝试可变模板,但没有找到任何解决问题的方法,那么我建议您查看下面的代码:

#include <iostream>

template<int ...Values>
void foo2()
{
    int len = sizeof...(Values);
    int vals[] = {Values...};

    for (int i = 0; i < len; ++i)
    {
        std::cout << vals[i] << std::endl;
    }
}

int main()
{
    foo2<1, 2, 3, 4>();

    return 0;
}
#包括
模板
void foo2()
{
int len=sizeof…(值);
int vals[]={Values…};
对于(int i=0;i
void foo(int);

template<typename ...Args>
void foo(int first, Args... more)
{
   foo(first);
   foo(more...);
}
void foo(int);
模板
void foo(int优先,Args…更多)
{
傅(第一),;
福(更多…);
}

顶部答案的一种变体,它将拒绝隐式转换为
int
,如果您喜欢:

#include <type_traits>

void foo(int);

template<typename Arg1, typename ...Args>
void foo(Arg1 first, Args... more)
{
   static_assert(std::is_same_v<Arg1, int>, "foo called with non-int argument");
   foo(first);
   foo(more...);
}
#包括
void foo(int);
模板
void foo(Arg1优先,Args…更多)
{
静态断言(std::is_same_v,“用非int参数调用foo”);
傅(第一),;
福(更多…);
}

在大多数情况下,使用具有相同类型参数包的可变模板没有意义,但在启用c++11的编译器中:

#include <iostream>
#include <tuple>

template <typename ... Args>
void foo(Args ... args) {
    using type = typename std::tuple_element<0, std::tuple<Args...>>::type;
    const auto len = std::tuple_size<std::tuple<Args...>> {};
    type vals[] = {args...};

    for (size_t it = 0; it < len; ++it) {
        std::cout << vals[it] << std::endl;
    }
}

int32_t main(int argc, char** argv) {
    foo(1, 2);
    foo(1.1, 2.2);
    foo("1", "2");
    return EXIT_SUCCESS;
}
#包括
#包括
模板
void foo(Args…Args){
使用type=typename std::tuple\u元素::type;
const auto len=std::tuple_size{};
键入vals[]={args…};
用于(大小\u t it=0;itstd::你能不能使用
enable_if
来确保所有类型都是int。如果你给它一堆int,代码就会工作。如果你给它一些别的东西,它就不工作了。看起来任务完成了。问题在哪里?我想问题是,是否有可能在编译时确保它们是int。一个
静态断言
会如果
foo
的主体中有任何内容要求所有类型都是
int
s或可转换为
int
s,则使用
@znby是相同的
-如果您编写了一个调用,而调用中没有参数,那么在编译时您就会知道。但是,如果您需要知道编译时参数的数量,这种解决方法是不够的,因为
初始值设定项\u list
不提供
constepr size()
member.AFAIK,对于变量模板,没有办法用
是否相同/是否可转换
检查。@user2523017你是对的,使用这个解决方案,我们无法在编译时获得参数的数量。这个答案更适合OP的要求。这个解决方案唯一的缺点是递归部分。但是现在我用c你可以看到一个更好的解决方案,甚至不能使用C++17和折叠表达式。@mic什么是更好的解决方案?这个解决方案的缺点是它不能接受0个参数。@candy chiu在我最后的评论中有一个输入错误:“但现在我看不到…”(只是为了澄清)。除此之外,你可以轻松添加另一个重载:
foo()
支持0个参数。
std::forward
是冗余的,除非使用了
Args&
而不是
Args
#include <type_traits>

void foo(int);

template<typename Arg1, typename ...Args>
void foo(Arg1 first, Args... more)
{
   static_assert(std::is_same_v<Arg1, int>, "foo called with non-int argument");
   foo(first);
   foo(more...);
}
#include <iostream>
#include <tuple>

template <typename ... Args>
void foo(Args ... args) {
    using type = typename std::tuple_element<0, std::tuple<Args...>>::type;
    const auto len = std::tuple_size<std::tuple<Args...>> {};
    type vals[] = {args...};

    for (size_t it = 0; it < len; ++it) {
        std::cout << vals[it] << std::endl;
    }
}

int32_t main(int argc, char** argv) {
    foo(1, 2);
    foo(1.1, 2.2);
    foo("1", "2");
    return EXIT_SUCCESS;
}