【问题标题】:Variadic templates without function parameters不带函数参数的可变参数模板
【发布时间】:2012-05-03 22:51:12
【问题描述】:

我可以使用可变参数模板而不使用模板参数作为函数参数吗?

当我使用它们时,它会编译:

#include <iostream>
using namespace std;

template<class First>
void print(First first)
{
    cout << 1 << endl;
}

template<class First, class ... Rest>
void print(First first, Rest ...rest)
{
    cout << 1 << endl;
    print<Rest...>(rest...);
}

int main()
{
    print<int,int,int>(1,2,3);
}

但是当我不使用它们时,它不会编译并抱怨歧义:

#include <iostream>
using namespace std;

template<class First>
void print()
{
    cout << 1 << endl;
}

template<class First, class ... Rest>
void print()
{
    cout << 1 << endl;
    print<Rest...>();
}

int main()
{
    print<int,int,int>();
}

不幸的是,我想作为模板参数提供的类是不可实例化的(它们具有在模板函数内部调用的静态函数)。 有没有办法做到这一点?

【问题讨论】:

  • 如果你需要一个给定类型的 unevalated 表达式,你可以使用std::declval&lt;T&gt;()。适用于任何T,无论其是否可构造。
  • 至于为什么无参数版本不起作用:没有参数,print&lt;int, {}&gt;print&lt;int&gt;的重载同样好,而有参数print&lt;int&gt;(3)比@987654328更好的匹配@(其中{} 表示“无”)。正如 CatPusPus 所建议的那样,不使用重载是标准方法;而且由于您无论如何都没有推断出您的论点,所以这是最简单的解决方案。
  • 我打算发布一个答案,但 n.m.已经发过了。

标签: c++ templates c++11 variadic-templates function-parameter


【解决方案1】:
template<class First> // 1 template parameter
void print()
{
    cout << 1 << endl;
}

#if 0
template<class First, class ... Rest> // >=1 template parameters -- ambiguity!
void print()
{
    cout << 1 << endl;
    print<Rest...>();
}
#endif

template<class First, class Second, class ... Rest> // >=2 template parameters
void print()
{
    cout << 1 << endl;
    print<Second, Rest...>();
}

【讨论】:

  • 您可以通过从最底层版本调用 print&lt;First&gt;() 来消除代码重复,而不是重复 cout 行。我想。
【解决方案2】:

让它成为一个类型。

template <typename... Ts>
struct print_impl;

template <typename T>
struct print_impl<T> {
    static void run() {
        std::cout << 1 << "\n";
    }
};

template <typename T, typename... Ts>
struct print_impl<T, Ts...> {
    static void run() {
        std::cout << 1 << "\n";
        print_impl<Ts...>::run();
    }
};

template <typename... Ts>
void print() {
    print_impl<Ts...>::run();
}

int main() {
    print<int, int, int>();
    return 0;
}

【讨论】:

  • 我认为这里的复杂性是不值得的。 nm 的解决方案要简单得多。
猜你喜欢
  • 2020-05-14
  • 1970-01-01
  • 2014-09-08
  • 2016-12-01
  • 2021-10-01
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多