Оператор перегрузки << принять шаблонную функцию - PullRequest
5 голосов
/ 03 августа 2010

Я пытаюсь написать расширяемую грамматику, используя функции, но не могу найти правильный синтаксис для принятия шаблонной функции.Я использую Visual C ++ 2008. Он будет принимать переменную того же типа, что и функция шаблона, или похожую функцию без шаблона, но не саму функцию шаблона.

Ошибка 1 ошибка C2679: двоичный файл «<<»: не найден оператор, который принимает правый операнд типа «перегруженная функция» (или нет допустимого преобразования) (строка <code>***)

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 ]

3 голосов
/ 03 августа 2010

Ваш код выглядит нормально для меня, и 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>); // ***
}
0 голосов
/ 23 августа 2016

MSVC 2013 все еще содержит ту же ошибку, но по крайней мере теперь вы можете использовать более новый синтаксис шаблона псевдонима C ++ 11, если вы используете решение для приведения:

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

Затем выполните приведение как это:

Grammar() << Fptr<int>(Expression<int>) << endl;
0 голосов
/ 03 августа 2010

Как еще один обходной путь, я смог заставить его работать на 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> );
0 голосов
/ 03 августа 2010

Изменить это:

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
    }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...