【问题标题】:aliasing a variadic template function给可变参数模板函数起别名
【发布时间】:2014-06-20 15:03:59
【问题描述】:

我有一个可变参数函数,例如:

void test(int){}

template<typename T,typename...Args>
void test(int& sum,T v,Args... args)
{
    sum+=v;
    test(sum,args...);
}

我想给它起别名:

auto sum = test;//error : can not deduce auto from test
int main()
{
    int res=0;
    test(res,4,7);
    std::cout<<res;
}

我尝试使用std::bind,但它不适用于可变参数函数,因为它需要占位符...

是否可以给变量函数起别名?

【问题讨论】:

  • auto sum = [](auto&amp;&amp;... pp) { return test(std::forward&lt;decltype(pp)&gt;(pp)...); }; 或类似的东西。不过,这不是真正的别名。例如,您不能使用auto x = &amp;sum&lt;int, double&gt;;

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


【解决方案1】:

在 C++1y 中:

#include <iostream>

void test(int){}

template<typename T,typename...Args>
void test(int& sum,T v,Args... args)
{
  sum+=v;
  test(sum,args...);
}

template<typename T,typename...Args>
decltype(test<T, Args...>)* sum = &(test<T, Args...>);

int     main(void)
{
  int   res = 0;
  sum<int, int>(res, 4, 7);
  std::cout << res << std::endl;
}

或者将其包装在另一个可变参数函数和std::forward 参数中:

template<typename T,typename...Args>
void    other(int&sum, T v, Args&&... args)
{
  test(sum, std::move(v), std::forward<Args>(args)...);
}

【讨论】:

  • 很有趣,但我怀疑类型推导是否适用于这个“别名”。
  • @dyp 目前它没有与通常的编译器一起使用,但也许有一天还没有:)
  • 嗯,我怀疑 variable templates 的语法是否支持这一点;因为定义的模板没有与函数调用的参数匹配的模式。考虑变量模板的特化。只有在非常受限的上下文中,变量模板才能被视为别名,编译器必须“看穿”这一抽象层。
  • std::forward&lt;T&gt;(v) 不是必需的,因为T v 不是通用参考。 std::move(v) 就足够了。
  • @dyp 已更新 :) 至于推论,我同意你的看法,尽管尝试自动推论的一个明显情况是在变量模板上调用 operator() 时,这意味着它很可能是可调用的可能完全由那个电话推断出来。但我不是编译器作者,所以这完全是猜测^^
【解决方案2】:

你正在尝试的与

没有太大区别
void test(int)
{
}

void test(double, int)
{
}

auto a = test;

编译器无法检测您要使用的重载。

您可以通过以下方式明确说明要将哪个test 分配给a

auto a = (void(*)(int))test;

如果你想添加可变参数模板版本,你可以使用:

template<typename T,typename...Args>
void test(int& sum,T v,Args... args)
{
    sum+=v;
    test(sum,args...);
}

auto a = test<int, int, int>;

【讨论】:

  • 顺便说一句,如果他想要test(double, int),他可以这样做:ideone.com/KFJnjh
  • 我知道,我一直在寻找一种实现可变参数函数的方法。 @dyp 解决方案似乎适用于 gcc 4.9,coliru.stacked-crooked.com/a/d3aabbd801efe463
  • 它没有回答问题。顺便说一句 auto a = test&lt;int, int, int&gt;; 不起作用:coliru.stacked-crooked.com/a/4c19105de2b3d597
  • 对于三个参数,你使用auto a = test&lt;int, int&gt;
  • @awesomeyi 我需要在一般情况下工作的东西,我的问题只是我的代码的简化版本,我不能将 auto 用于所有可能的方式!
【解决方案3】:

这不是别名。auto a = test 试图声明一个与test 具有相同类型的变量 a 并使它们相等。由于 test 不是单个函数,而是一个函数模板(最重要的是,您甚至可以重载函数),编译器无法决定 a 的类型应该是什么。

要给模板起别名,或者实际上是任何符号,您可以使用 using 关键字。

using a = test;

编辑:抱歉,这个只适用于类型而不是函数。

【讨论】:

  • 你不能用 using 为模板函数加上别名!
  • 是的,我的错,不过你可以给仿函数起别名。那么目前在 C++ 中是不可能的。
猜你喜欢
  • 2016-11-18
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
  • 2014-10-20
  • 1970-01-01
  • 2011-11-15
  • 1970-01-01
相关资源
最近更新 更多