【问题标题】:C++ template for function call operator函数调用运算符的 C++ 模板
【发布时间】:2015-05-08 03:15:59
【问题描述】:

我尝试在以下程序中使用模板进行函数调用运算符重载:

#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 错误。我不知道我做错了什么。谁能帮我知道问题提前谢谢。

【问题讨论】:

    标签: c++ templates operator-overloading


    【解决方案1】:

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

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

    operator()() 是一个以() 为参数的模板成员函数。所以,它的名字是operator(),它的参数列表是()。因此,要引用它,您需要使用apple.operator()(它的名称),然后是&lt;int&gt;(模板参数),然后是()(参数列表)。将名称operator() 替换为FUNCTION,所以operator()()FUNCTION(),你会看到模式。在您的情况下,apple&lt;int&gt;() 在模板实例化 apple&lt;int&gt; 对象上调用非模板 operator()(),即 apple&lt;int&gt;.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 指定为返回类型,但在更复杂的声明中可能非常有用。

    【讨论】:

    • 很好的答案,谢谢。我能知道为什么不能推断调用吗
    • @Dinesh,编译器推断类型的唯一方法是将其与某个表达式匹配。在您的情况下,在呼叫站点没有要匹配的表达式。
    • 是的,但是我在这两种情况下都明确指定了类型,我不明白为什么错误只出现在运算符重载函数调用中
    • auto完全等同于写int时,有什么意义呢?
    • @T.C.在这种情况下绝对没有意义,可能是当返回是typename T::some_inner_type::some_mess。我只是指出,OP 并不真正需要带有 void 参数的模板仿函数运算符。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多