c++ - 没有形式参数的可变函数模板

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

这就是我想要做的:

// base case
void f() {}

template <typename T, typename... Ts>
void f() {
    // do something with T
    f<Ts...>();
}

int main() {
    f<int, float, char>();
    return 0;
}

它不编译:

prog.cpp: In instantiation of ‘void f() [with T = char; Ts = {}]’:
prog.cpp:6:5:   recursively required from ‘void f() [with T = float; Ts = {char}]’
prog.cpp:6:5:   required from ‘void f() [with T = int; Ts = {float, char}]’
prog.cpp:10:25:   required from here
prog.cpp:6:5: error: no matching function for call to ‘f()’
prog.cpp:6:5: note: candidate is:
prog.cpp:4:6: note: template<class T, class ... Ts> void f()
prog.cpp:4:6: note:   template argument deduction/substitution failed:
prog.cpp:6:5: note:   couldn't deduce template parameter ‘T’

This线程显示了一种解决此问题的方法,但基本情况必须是模板。我不太喜欢它,因为据我所知,我将不得不复制适用于 T 的代码。有没有办法避免这种情况?

到目前为止,我想出了两个解决方案 ( http://ideone.com/nPqU0l ):

template <typename...> struct types_helper {};

// base case
void f(types_helper<>) {}

template <typename T, typename... Ts>
void f(types_helper<T, Ts...>) {
    // do something with T
    f(types_helper<Ts...>());
}

int main() {
    f(types_helper<int, float, char>());
    return 0;
}

http://ideone.com/yyg6y9 :

#include <type_traits>

struct end_of_list;

template <typename T>
void f() {
    static_assert(std::is_same<T, end_of_list>::value, "error");
}

template <typename T1, typename T2, typename... Ts>
void f() {
    // do something with T
    f<T2, Ts...>();
}

int main() {
    f<int, float, char, end_of_list>();
    return 0;
}

我想知道是否有更好的方法来做到这一点。

最佳答案

另一种方法是将非模板函数 f 变成可变模板函数,它接受零个或多个模板参数(另一个 f 需要一个或多个模板参数) .然后为了避免歧义,SFINAE 在参数个数不为零时去掉这个模板函数。好吧,一个代码胜过 1000 个单词:

#include <type_traits>

template <typename... Ts>
typename std::enable_if<sizeof...(Ts) == 0>::type f() {
}

template <typename T, typename... Ts>
void f() {
    // do something with T
    f<Ts...>();
}

关于c++ - 没有形式参数的可变函数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16758620/

相关文章:

c++ - 为什么我的模板参数包不起作用?

c++ - 我的 CRTP 数学数组类 : compilation fails

c++ - 可以具有存储相互连续的实例的类似 vector 的容器?

没有类型推导的 LValue 和 Rvalue 的 C++ 引用

c++ - 使 Qt 应用程序在最后一个窗口关闭时不退出

c++ - OpenCV : Assertion failed using one of the two constructors of SIFT

c++ - 将 c++0x 线程与 gio GCancellable 混合使用是否合法?

c++ - 那些被忽视的非标准 C++ 库中有哪些好的部分?

c++ - 带有模板的类的构造方法

c++ - 编写一个从类型列表返回类型的元函数,该类型列表具有 C++11 中给定类型的 typedef