То, что я пытаюсь сделать, - создать функтор, который может принимать различные функции в качестве аргументов.Передача объекта функции конструктору
Редактировать: причина моей проблемы, «самый раздражающий синтаксический анализ», и раствор хорошо описан: см this question and answer, весь most-vexing-parse тега, и даже 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()
...
Иногда стоит компиляции кода с лязгом, поскольку он обеспечивает лучшие сообщения об ошибках. В этом случае clang показывает предупреждение: «круглые скобки были неоднозначны как объявление функции [-Wvexing-parse]». Это объясняет другие ошибки компиляции. –
Компилятор считает, что 'f' является объявлением функции. Если у вас есть доступ к C++ 11, используйте единый синтаксис инициализации, который был разработан для обработки таких ситуаций 'doer> f {std :: умножает ()};'. –
legends2k
@ legendends2k Спасибо за это, выглядит наиболее убедительно, хотя есть, по крайней мере, два способа записи. Не уверен, что это следует рассматривать как «дубликат», поскольку название другого вопроса было не слишком полезно в моем случае. –