Что делать, если тип возвращаемого значения определяется во время выполнения в C++?

Вот сценарий: у меня есть файл матрицы для столбца в двоичном формате для загрузки, матрица может быть короткой, int, double и т. Д. Концептуально что-то подобное должно быть сделано:

Mat<xxx> loadfile(std::string filename)
{
    std::string matType = gettype(filename);
    Mat<matType> mat;
    mat.load(filename);
    return mat;
}

Но проблема в том, что, поскольку я не знаю тип возвращаемого значения, я не могу определить функцию в первую очередь.

1 ответ

Ты не сможешь это сделать. В простейшей форме, loadfile должен быть такой шаблон

template<typename T>
Mat<T> loadfile(std::string filename)
{
    Mat<T> mat;
    mat.load(filename);
    return mat;
}

поэтому пользователь явно указывает тип

Mat<int> mat = loadfile<int>("filename.mat");

Теперь, если в файл встроена информация о типе, вы можете, например, выполнить во время выполнения исключение, если T не соответствует фактическому сохраненному типу.

Если количество возможных типов ограничено, вы можете использовать функцию шаблона, скажем run<T> указать, что вам нужно делать с данными (алгоритм) и выбрать в зависимости от ввода, например

is_type_real(filename) ? run<double>(filename) : run<int>(filename);

В этом случае компилятор создает все возможные (две здесь) версии алгоритма (специализации) во время компиляции, а соответствующая вызывается во время выполнения.

Эта идея может быть расширена до таблицы поиска указателей на функции, которая может выглядеть примерно так, как вы думали:

template<typename T>
void run(std::string filename)
{
   Mat<T> mat = loadfile<T>(filename); 
   // run algorithm for type T
}

using fun = void(*)(std::string);

fun lookup[4] = { run<int>, run<long>, run<float>, run<double> };

enum matrix_type { Int, Long, Float, Double };

matrix_type get_type(std::string filename)
{
   // read type from file, return it as a matrix_type
};

int main()
{
    std::string filename = "filename.mat";
    matrix_type type = get_type(filename);
    lookup[type](filename);
}

Переходя от времени выполнения к миру времени компиляции, я думаю, что это как можно ближе. Это может быть дополнительно организовано, см., Например, здесь и этот вопрос. Но я просто хотел дать идею.

Другие вопросы по тегам