Мотивация, если она помогает: У меня есть функции-члены struct, которые являются ядрами радиальных базисных функций.Они называются 1e06 x 15 x 1e05 раз в численном моделировании.Я рассчитываю на девиртуализацию встроенных виртуальных функций - это не то, что я хочу сделать для такого количества вызовов функций.Кроме того, структуры (ядра RBF) уже используются в качестве параметров шаблона большего класса интерполяции.
Минимальный рабочий пример
У меня есть функция g()
, котораявсегда одно и то же, и я хочу использовать его повторно, поэтому я упаковываю его в базовый класс.
Функция g()
вызывает функцию f()
, которая отличается в производных классах.
Я не хочу использовать функции virtual
для разрешения имен функций во время выполнения, потому что это сопряжено с дополнительными затратами (я измерял это в своем коде, это дает эффект).
Вот пример:
#include <iostream>
struct A
{
double f() const { return 0; };
void g() const
{
std::cout << f() << std::endl;
}
};
struct B : private A
{
using A::g;
double f() const { return 1; };
};
struct C : private A
{
using A::g;
double f() const { return 2; };
};
int main()
{
B b;
C c;
b.g(); // Outputs 0 instead of 1
c.g(); // Outputs 0 instead of 2
}
Я ожидал, что механизм разрешения имен выяснит, что я хочу использовать «A :: g ()», но затем вернуться к «B»или «C» для разрешения функции «f ()».Что-то наподобие: «когда я знаю тип во время компиляции, я попытаюсь сначала разрешить все имена в этом типе и выполнить поиск имени по объектам / родителям, чего-то не хватает, а затем вернуться к типу, из которого меня вызывали».Однако, похоже, выясняется, что используется «A :: g ()», затем он сидит в «A» и просто выбирает «A :: f ()», хотя фактический вызов «g ()» поступил из«Б» и «С».
Это можно решить с помощью виртуальных функций, , но я не понимаю и хотел бы узнать причину, по которой поиск имени придерживается родительского класса, когда типы известны во время компиляции .
Как заставить это работать без виртуальных функций?