【问题标题】:Overloading operator<< to accept a template function重载 operator<< 以接受模板函数
【发布时间】:2011-03-24 15:41:35
【问题描述】:

我正在尝试使用函数编写可扩展的语法,但似乎找不到接受模板函数的正确语法。我正在使用 Visual C++ 2008。它将接受与模板函数相同类型的变量,或类似的非模板函数,但不接受模板函数本身。

错误 1 ​​错误 C2679: 二进制 '***)

class Grammar {
    friend Grammar operator << ( const Grammar& lhs, const char* rhs ) {
        return lhs; // append rhs to grammar
    }
    template<typename T>
    friend Grammar operator << ( const Grammar& lhs, T (*rhs) () ) {
        return lhs; // append rhs() to grammar
    }
};

template<typename T>
class ExpressionParticle {
};

template<typename T>
ExpressionParticle<T> Expression () ;

ExpressionParticle<int> ExpressionInt ();

int _tmain ( int argc, _TCHAR *argv[] )
{
    ExpressionParticle<int> (*p)();

    p = Expression<int>;

    Grammar() << "p";
    Grammar() << p;
    Grammar() << ExpressionInt;
    Grammar() << Expression<int>; // ***

Expression&lt;int&gt;不是上面p的类型是什么?它的类型和ExpressionInt的类型有什么不同。

【问题讨论】:

  • FWIW,使用 g++ 4.4.1 编译

标签: c++ templates operator-overloading


【解决方案1】:

MSVC 2013 仍然包含相同的错误,但至少现在您可以使用更新的 C++11 别名模板语法,如果您使用强制转换解决方案:

template <typename T>
using Fptr = ExpressionParticle<T>(*)();

然后像这样进行演员表:

Grammar() << Fptr<int>(Expression<int>) << endl;

【讨论】:

    【解决方案2】:

    作为另一种解决方法,我能够通过强制转换使其在 VS2010 上运行。为方便起见,我使用了 typedef。 VS2008 可能也一样。

    int _tmain ( int argc, _TCHAR *argv[] )
    {
       typedef ExpressionParticle< int > (*FCN)();
    
       ExpressionParticle<int> (*p)() = Expression<int>; 
    
       Grammar() << "p"; 
       Grammar() << p; 
       Grammar() << ExpressionInt; 
       Grammar() << static_cast< FCN >( Expression<int> );
    

    【讨论】:

      【解决方案3】:

      您的代码对我来说看起来不错,g++ 也可以。这似乎是 Visual Studio 中奇怪的重载解析错误。 VS2005 似乎也有同样的问题。一种可能的解决方法是(用 VS2005 测试):

      template<class T>
      T id(T t)  {return t; }
      int main ()
      {
          ExpressionParticle<int> (*p)();
      
          p = Expression<int>;
      
          Grammar() << "p";
          Grammar() << p;
          Grammar() << ExpressionInt;
          Grammar() << id(Expression<int>); // ***
      }
      

      【讨论】:

        【解决方案4】:

        改变这个:

        class Grammar {
            friend Grammar operator << ( const Grammar& lhs, const char* rhs ) {
                return lhs; // append rhs to grammar
            }
            template<typename T>
            friend Grammar operator << ( const Grammar& lhs, T (*rhs) () ) {
                return lhs; // append rhs() to grammar
            }
        };
        

        到这里:

        class Grammar {
        public:
            Grammar& operator << ( const char* rhs ) {
                return *this; // append rhs to grammar
            }
            template<typename T>
            Grammar& operator << ( const T &rhs) {
                return *this; // append rhs() to grammar
            }
        };
        

        【讨论】:

        • Grammar() &lt;&lt; Expression&lt;int&gt;(); 的含义完全不同。
        • 啊!...我的坏..我没有注意到它的那一部分。但是他超载operator &lt;&lt; 的方式是错误的,IMO。我现在就改一下。
        • @Luther 对不起.. 但是Expression&lt;int&gt;(); 的含义又是完全不同的吗?它是一个模板函数,该函数应该像函数一样被调用。不是吗?我在 Visual Studio 2008 中解决了它,它确实编译了它!
        • 他想要函数指针 Expression 而不是调用 Expression 的结果。显然他想稍后调用该函数以产生一些副作用。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-03
        • 2018-09-09
        • 2016-03-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多