Andrei Alexandrescu发表了题为:Variadic Templates are Funadic的精彩演讲。
他提出了以下3个不同的扩展:
template <class... Ts> void fun( Ts... vs ) {
gun( A<Ts...>::hun(vs)...);
gun( A<Ts...>::hun(vs...));
gun( A<Ts>::hun(vs)...);
}
他解释道:
致电1:
扩展所有Ts
以便class A
进行设置,
然后拨打hun(vs)
然后在将所有参数传递到gun
致电2:
分别展开所有Ts
和所有vs
致电3:
锁定步骤中的Expnads,即:
展开Ts
的参数1和vs
的参数1
展开Ts
的参数2和vs
的参数2
展开Ts
的参数n和vs
的参数n
关于可变参数模板的其他讨论似乎只涵盖了简单的可变参数类模板和可变参数函数,例如typesafe printf等。我不确定这些不同类型的扩展如何影响代码以及每种类型的用途。
有没有人举例说明每种扩展的应用?
答案 0 :(得分:15)
#include <iostream>
#include <memory>
#include <typeinfo>
#include <cstdlib>
#include <cxxabi.h>
template <typename T>
std::unique_ptr<char, void(*)(void*)>
type_name()
{
return std::unique_ptr<char, void(*)(void*)>
(
__cxxabiv1::__cxa_demangle(typeid(T).name(), nullptr,
nullptr, nullptr),
std::free
);
}
void display() {}
template <class T>
void
display()
{
std::cout << type_name<T>().get() << ' ';
}
template <class T, class T2, class ...Tail>
void
display()
{
std::cout << type_name<T>().get() << ' ';
display<T2, Tail...>();
}
template <class... Ts>
struct A
{
template <class... Us>
static
int
hun(Us... us)
{
std::cout << "A<";
display<Ts...>();
std::cout << ">::hun(";
display<Us...>();
std::cout << ")\n";
return 0;
}
};
template <class ...T>
void gun(T...) {}
template <class... Ts> void fun( Ts... vs )
{
std::cout << "gun( A<Ts...>::hun(vs)...);\n";
gun( A<Ts...>::hun(vs)...);
std::cout << "\ngun( A<Ts...>::hun(vs...));\n";
gun( A<Ts...>::hun(vs...));
std::cout << "\ngun( A<Ts>::hun(vs)...);\n";
gun( A<Ts>::hun(vs)...);
}
int main()
{
fun(1, 'a', 2.3);
}
输出:
gun( A<Ts...>::hun(vs)...);
A<int char double >::hun(int )
A<int char double >::hun(char )
A<int char double >::hun(double )
gun( A<Ts...>::hun(vs...));
A<int char double >::hun(int char double )
gun( A<Ts>::hun(vs)...);
A<int >::hun(int )
A<char >::hun(char )
A<double >::hun(double )
答案 1 :(得分:7)
案例2和3在任何涉及可变包的代码中都非常常见。
template<typename... T>
void f(T&&... t)
{
// Case 2:
auto t2 = std::tuple<T...>(t...);
// Case 3:
auto t3 = std::make_tuple(std::forward<T>(t)...);
}
查看我自己的代码,我找不到案例1的任何幸存示例。我可能在过去的某个detail
命名空间中使用它来获得帮助器,但我不确定。我认为大部分时间都不会普遍甚至是必要的。