Reputation: 49331
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
.
Upvotes: 5
Views: 765
Reputation: 4295
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;
Upvotes: 0
Reputation: 1
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> );
Upvotes: 0
Reputation: 28807
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>); // ***
}
Upvotes: 3
Reputation: 6641
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
}
};
Upvotes: 0