2015-08-04 2 views
1

То, что я пытаюсь сделать, - создать функтор, который может принимать различные функции в качестве аргументов.Передача объекта функции конструктору

Редактировать: причина моей проблемы, «самый раздражающий синтаксический анализ», и раствор хорошо описан: см this question and answer, весь тега, и даже wikipedia page. Тем не менее, я не смог идентифицировать проблему, прежде чем задавать вопросы, и оставим этот вопрос, поскольку это может помочь другим.

Что я сделал:

В файле заголовка functor.hpp:

#ifndef FUNCTOR_HPP 
#define FUNCTOR_HPP 

#include <functional> 

template <typename T, typename BinOp = typename std::plus<T>> 
struct doer { 
    BinOp op; 
    doer(BinOp o = std::plus<T>()) : op(o) {} 
    T operator()(const T& a, const T& b) const 
    { return op(a, b); } 
}; 

#endif // FUNCTOR_HPP 

С этим заголовком, я могу написать программу functor.cpp так:

#include <iostream> 
#include "functor.hpp" 

int main() 
{ 
    doer<int> f; 
    std::cout << f(3, 7) << std::endl; 
} 

и я могу скомпилировать и запустите его, чтобы получить, как ожидалось:

$ make functor 
g++ -std=c++14 -pedantic -Wall functor.cpp -o functor 
$ ./functor 
10 
$ 

Я изо всех сил пытаюсь найти способ создать экземпляр своего doer с помощью другого оператора (не std::plus<T>).

doer<int, std::multiplies<int>> f2(std::multiplies<int>()); 

компилируется без проблем, но я не смог придумать, как назвать f2(3, 7), чтобы получить продукт 21. Например, если добавить еще одну строку в программе:

int r = f2(3, 7); 

и попытаться собрать, я получаю:

$ make functor 
g++ -std=c++14 -pedantic -Wall functor.cpp -o functor 
functor.cpp: In function ‘int main()’: 
functor.cpp:10:20: error: invalid conversion from ‘int’ to ‘std::multiplies<int> (*)()’ [-fpermissive] 
    int r = f2(3, 7); 
        ^
functor.cpp:10:20: error: too many arguments to function ‘doer<int, std::multiplies<int> > f2(std::multiplies<int> (*)())’ 
functor.cpp:9:37: note: declared here 
    doer<int, std::multiplies<int>> f2(std::multiplies<int>()); 
            ^
functor.cpp:10:20: error: cannot convert ‘doer<int, std::multiplies<int> >’ to ‘int’ in initialization 
    int r = f2(3, 7); 
        ^

Что происходит? Кажется почти как f2(3, 7) как-то не называет перегруженный operator() ...

+1

Иногда стоит компиляции кода с лязгом, поскольку он обеспечивает лучшие сообщения об ошибках. В этом случае clang показывает предупреждение: «круглые скобки были неоднозначны как объявление функции [-Wvexing-parse]». Это объясняет другие ошибки компиляции. –

+2

Компилятор считает, что 'f' является объявлением функции. Если у вас есть доступ к C++ 11, используйте единый синтаксис инициализации, который был разработан для обработки таких ситуаций 'doer > f {std :: умножает ()};'. – legends2k

+0

@ legendends2k Спасибо за это, выглядит наиболее убедительно, хотя есть, по крайней мере, два способа записи. Не уверен, что это следует рассматривать как «дубликат», поскольку название другого вопроса было не слишком полезно в моем случае. –

ответ

1

Самое неприятное разбор. Попробуйте это:

doer<int, std::multiplies<int>> f2((std::multiplies<int>())); 

или это:

doer<int, std::multiplies<int>> f2 = std::multiplies<int>(); 

или это:

doer<int, std::multiplies<int>> f2{std::multiplies<int>()}; 
Смежные вопросы