重载运算符<<接受模板函数

发布于 2024-09-12 18:54:59 字数 1116 浏览 3 评论 0 原文

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

I'm trying to be able to write an extensible grammar using functions, but can't seem to find the right syntax for accepting a template function. I'm using Visual C++ 2008. It will accept a variable of the same type as the template function, or a similar non-template function, but not the template function itself.

Error 1 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion) ( line *** )

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>; // ***

What is the type of Expression<int> if it is not the type of p in above? How is its type different to the type of ExpressionInt.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

︶葆Ⅱㄣ 2024-09-19 18:54:59

你的代码对我来说看起来不错,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>); // ***
}

Your code looks OK to me, and g++ is fine with that too. This seems to be weird overload resolution bug in Visual Studio. VS2005 seems to have the same problem. A possible workaround is (tested with 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>); // ***
}
掀纱窥君容 2024-09-19 18:54:59

将此:更改

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

Change this:

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

to this:

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
    }
};
提赋 2024-09-19 18:54:59

作为另一种解决方法,我可以通过强制转换使其在 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> );

As another work-around, I was able to get it to work on VS2010 by casting. I used the typedef for convenience. VS2008 probably will work the same.

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> );
携君以终年 2024-09-19 18:54:59

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

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

然后像这样进行转换:

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

MSVC 2013 still contains the same bug, but at least now you can use the newer C++11 alias template syntax if you go with the casting solution:

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

Then do the cast like this:

Grammar() << Fptr<int>(Expression<int>) << endl;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文