代码之家  ›  专栏  ›  技术社区  ›  Pete Kirkham

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

  •  5
  • Pete Kirkham  · 技术社区  · 14 年前

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

    错误1错误C2679:二进制'<<':找不到接受类型为'overloaded function'的右侧操作数的运算符(或没有可接受的转换)(第行 *** )

    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 回复  |  直到 8 年前
        1
  •  3
  •   Nordic Mainframe    14 年前

    我觉得你的代码没问题,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>); // ***
    }
    
        2
  •  0
  •   Vite Falcon    14 年前

    改变这一点:

    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
        }
    };
    
        3
  •  0
  •   IvanK    14 年前

    作为另一项工作,我可以通过演员阵容让它在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> );
    
        4
  •  0
  •   Carlton    8 年前

    MSVC 2013仍然包含相同的bug,但至少现在您可以使用较新的C++ 11别名模板语法,如果您使用的是铸造解决方案:

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

    然后像这样做演员:

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