重载运算符<<接受模板功能

时间:2010-08-03 10:06:28

标签: c++ templates operator-overloading

我正在尝试使用函数编写可扩展语法,但似乎无法找到接受模板函数的正确语法。我正在使用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<int>的类型是什么,如果它不是上面的p类型?它的类型与ExpressionInt的类型有何不同。

4 个答案:

答案 0 :(得分: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>); // ***
}

答案 1 :(得分:0)

改变这个:

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
    }
};

答案 2 :(得分:0)

作为另一种解决方法,我能够通过施法让它在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 :(得分:0)

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

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

然后像这样做演员:

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