есть такая функция, которая принимает другую функцию:
GLvoid Graphics::SceneGraph::Node::childrenForEach(GLvoid(*callback)(Node* child)) noexcept
{
Node* iterator = mChild;
while (iterator)
{
callback(iterator);
iterator = iterator->mNextNode;
}
}
Хочу вызвать ее следующим образом:
Tools::ShaderProgram& shader = mShaderManager.getShader(BASE_SHADER);
shader.use();
if (mRootNode->isExistChildren())
{
mRootNode->childrenForEach([&shader](Node* child)
{
if (child->isExistMesh())
{
shader.setUniformMatrix("modelMatrix", child->getTransformation());
child->getMesh().draw();
}
});
}
Но получаю следующую ошибку:
E0413 no suitable conversion function from "lambda []void (Graphics::SceneGraph::Node *child)->void" to "GLvoid (*)(Graphics::SceneGraph::Node *child)"
Что можно придумать, чтобы исправить это?
GLvoid Graphics::SceneGraph::Node::childrenForEach(GLvoid(*callback)(Node* child)) noexcept
{
Node* iterator = mChild;
while (iterator)
{
callback(iterator);
iterator = iterator->mNextNode;
}
}
В эту функцию нельзя передавать лямбды, сюда нужно передавать свободную функцию или статическу функцию.
Передать лямбдю можно только в том случае, когда она может быть преобразована в свободную функцию, а такое возможно только когда она не захватывает переменные из вне.
Самый лучшим вариантом, будет изменить сигнатуру функции childrenForEach
на:
GLvoid Graphics::SceneGraph::Node::childrenForEach(std::function<GLvoid(Node *)> callback)) noexcept
{
Node* iterator = mChild;
while (iterator)
{
callback(iterator);
iterator = iterator->mNextNode;
}
}
Если это невозможно, то отказаться от захвата переменных в лямбду и искать другие пути для доступа к shader
:
mRootNode->childrenForEach([](Node* child)
{
if (child->isExistMesh())
{
//shader.setUniformMatrix("modelMatrix", child->getTransformation());
child->getMesh().draw();
}
});
Возможно вообще отказаться от использования функции childrenForEach
и самому организовать обход элементов.
Дополнено:
По поводу других способов доступа к переменной: без описания типа Graphics::SceneGraph::Node
сложно что-то сказать, но скорее всего там есть методы для прохода по всем дочерним элементам без колбек функций.
Другим способом будет сделать переменную shader
но я бы не назвал это хорошим решением. Дайте ссылку где почитать про Graphics::SceneGraph::Node
и тогда будет проще помочь.
Если вы хотите иметь возможность передавать лямбды с захватом, то придется либо делать childrenForEach
шаблонной
template <typename F>
GLvoid Graphics::SceneGraph::Node::childrenForEach(F callback) noexcept
{
...
}
(и соответствующим образом подправить объявление в классе).
Либо использовать std::function
GLvoid Graphics::SceneGraph::Node::childrenForEach(std::function<GLvoid(Node*)>) noexcept
{
...
}
Для такой небольшой функции лучше подойдет как раз первый вариант, ибо он не влечет подавления оптимизаций и накладных расходов на каждый вызов, связанных с std::function
.
Однако еще лучшим вариантом будет полное отвязывание логики итерирования от вашего класса. В идеале: реализация логики итерирования через класс итератора по списку, а цикл ваш тогда будет записываться через обычный std::for_each
, в который вы сможете передавать что угодно в качестве функтора.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Задача написать функцию на С++,переводящую число X из 10 системы счисления в 3
Что такое "Thunk" в контексте виртуальных функций?(Как работает?)
Я начинающий в программированииЧитая книгу о С++ в главе посвященной указателям (в частности оператору delete), я наткнулся на то, что в среде...
У меня на странице несколько ViewНужно чтобы каждый анимировался после предыдущей