У меня есть две функции-члена шаблона, которые следует вызывать на основе соблюдения ограничения (полученного из определенного типа).
У меня есть шаблонная функция общего случая под названием addScheme, определенная следующим образом:
template <typename Field>
template <typename Scheme>
void TransportEquation<Field>::addScheme(Scheme&& scheme) {
if (scheme.needsCorrection()) {
_n_corrected_schemes++;
}
_schemes.emplace_back(std::make_shared<Scheme>(std::forward<Scheme>(scheme)));
}
Я добавил еще две функции для двух конкретных случаев.
Первая функция, с которой у меня нет проблем, тип шаблона Diffusion должен быть унаследован от IDiffusion:
template <typename Field>
template <typename Diffusion>
requires std::derived_from<Diffusion, IDiffusion>
void TransportEquation<Field>::addScheme(Diffusion&& diffusion) {
if (diffusion.needsCorrection()) {
_n_corrected_schemes++;
}
auto diff_scheme = std::make_shared<Diffusion>(std::forward<Diffusion>(diffusion));
_diff_scheme = diff_scheme;
_schemes.emplace_back(diff_scheme);
}
Моя проблема связана с другим, в котором схема должна быть получена из IConvection<G>, где G — другой тип шаблона:
template <typename Field>
template <typename Convection, typename G>
requires std::derived_from<Convection, scheme::convection::IConvection<G>>
void TransportEquation<Field>::addScheme(Convection&& convection) {
if (convection.needsCorrection()) {
_n_corrected_schemes++;
}
auto conv_scheme = std::make_shared<Convection>(std::forward<Convection>(convection));
_conv_scheme = conv_scheme;
_schemes.emplace_back(conv_scheme);
}
Эта функция никогда не вызывается, вместо нее всегда вызывается общая addScheme(Scheme&& scheme). Я не знаю, что не так с определением функции и почему ограничение никогда не выполняется?
Если будет полезно, то заявляю IConvection:
template <typename GradScheme = gradient::LeastSquares>
class IConvection {
// ...
};
и это производный тип, который никогда не соответствует ограничению addScheme(Convection&&) и вместо этого вызывается addScheme(Scheme&&):
template <typename G = gradient::LeastSquares>
class Upwind : public IConvection<G> {}
В частности, было бы полезно, если бы это был один фрагмент, который мы могли бы скопировать напрямую (без пропущенных заголовков или нескольких файлов).
@HolyBlackCat Я бы с удовольствием, но фрагменты являются частью большой базы кода. Можно ли опубликовать ссылку на GitHub в репозиторий?
В вашем коде G невозможно вывести, поэтому шаблон нельзя вызвать.
@n.m.couldbeanAI Спасибо, это тоже было мое первое предположение, но я не знаю, как сделать так, чтобы функция могла определить тип G.
«Можно ли опубликовать ссылку на репозиторий на GitHub?» Нет, это ваша домашняя работа — сократить ее до меньшего примера. Это объяснено в ссылке первого комментария. Иногда люди замечают ошибку только глазами, но если ситуация сложнее, пример очень помогает.
Вывести G невозможно ни в какой форме. Вы можете добавить в templateIConvection поле типа подтипа using Its_a_IConvection = bool;, а затем обнаружить тот факт, что любой IConvection<B> имеет этот специальный подтип.
Вы можете использовать черты is_template_base_of: requires is_template_base_of<scheme::convection::IConvection, Convection>::value.
Вы можете получить IConvection<G> из какого-то нешаблонного (возможно, пустого) базового класса IConvectionBase и вместо этого проверить происхождение от него.





У вас нет ничего уточняющего G, поэтому оно не выводится, поэтому шаблон никогда не сопоставляется.
Вы можете добавить псевдоним типа к IConvection
template <typename GradScheme = gradient::LeastSquares>
class IConvection {
// ...
public:
using gradient_scheme = GradScheme;
};
А затем найдите это в разделе «Требования». Любой тип, у которого нет псевдонима типа gradient_scheme, не соответствует этому шаблону, это не серьезная ошибка.
template <typename Field>
template <typename Convection>
requires std::derived_from<Convection, scheme::convection::IConvection<typename Convection::gradient_scheme>>
void TransportEquation<Field>::addScheme(Convection&& convection);
Приведите минимально воспроизводимый пример. Что-то, что можно напрямую скопировать/вставить и использовать для воспроизведения указанной проблемы/проблемы.