函数调用运算符的C ++模板

时间:2015-03-06 13:45:09

标签: c++ templates operator-overloading

我尝试使用模板进行函数调用操作符重载,如下面的程序所示:

#include <stdio.h>

struct Apple
{
   template <typename tn> tn value ();
   template <typename tn> tn operator () ();
};

template <> int Apple::value ()
{
   return 10;
}

template <> int Apple::operator () ()
{
   return 10;
}

int main()
{
   Apple apple;
   printf("Value : %d\n", apple<int>());
   printf("Value : %d\n", apple.value<int>());   
   return 0;
}

虽然第二次打印中的值函数调用未显示任何错误,但第一次打印中的函数调用操作符显示expected primary-expression错误。我不知道自己做错了什么。任何人都可以提前帮助我知道这个问题。

1 个答案:

答案 0 :(得分:11)

问题在于调用模板operator()main()的第二行)。在您的情况下,您需要显式指定返回类型,因为它无法推断,并且正确的方法是:

printf("Value : %d\n", apple.operator()<int>());

operator()()是一个模板成员函数,以()为参数。因此,其名称为operator(),其参数列表为()。因此,要引用它,您需要使用apple.operator()(其名称),然后使用<int>(模板参数),然后使用()(参数列表)。精神上将operator()替换为FUNCTION,因此operator()()FUNCTION(),您将看到该模式。在您的情况下,apple<int>()在模板实例化operator()()对象上调用非模板apple<int>,即apple<int>.operator()(),这不是您想要的。

定义这样的运算符很有用吗?可能不会,因为它会导致丑陋的语法。


您可以使用C ++ 14中的auto返回类型来实现您可能想要的功能,例如

#include <stdio.h>

struct Apple
{
   template <typename tn> tn value ();
   auto operator () ();
};

template <> int Apple::value ()
{
   return 10;
}

auto Apple::operator () () // not a template anymore, return type is deduced int
{
   return 10;
}

int main()
{
   Apple apple;
   printf("Value : %d\n", apple());
   printf("Value : %d\n", apple.value<int>());   
   return 0;
}

在这个示例中,auto并没有真正发光,因为您可以手动指定int作为返回类型,但在更复杂的声明中可能非常有用。