Функция C++, которая принимает параметризованный тип, включая подтипы

Библиотека OpenFOAM определяет два типа, volMesh и surfaceMesh, оба из которых наследуются от GeoMesh<fvMesh>. Я хочу определить функцию, которая принимает аргумент:

void foo(GeometricField<vector, fvsPatchField, GeoMesh<fvMesh> >& field) { ... }

Однако g++ выдает ошибку «недопустимая инициализация ссылочного типа», когда я пытаюсь вызвать функцию:

// surfaceVectorField is a typedef GeometricField<vector, fvsPatchField, surfaceMesh>
surfaceVectorField Uf( /* initialisation arguments */ ); 
foo(Uf);

Исходя из фона Java, эта проблема кажется похожей на забывание использовать объявление, такое как

void foo(GeometricField<vector, fvsPatchField, ? extends GeoMesh<fvMesh>> field) { ... }

Мне нужно избегать функций, специфичных для C++11, если это возможно.


person hertzsprung    schedule 21.10.2014    source источник
comment
можете ли вы добавить немного больше кода, а именно пример того, как вы пытаетесь вызвать свою функцию?   -  person Ashalynd    schedule 21.10.2014
comment
это ошибка вызова функции foo() или определения переменной Uf? stackoverflow.com/questions/9285627/   -  person Richard Chambers    schedule 21.10.2014
comment
возможно, он не может преобразовать ваш параметр SurfaceMesh в GeoMesh<fvMesh> или всю конструкцию в ссылку на правильный сложный тип.   -  person Ashalynd    schedule 21.10.2014
comment
@RichardChambers: ошибка связана с вызовом foo()   -  person hertzsprung    schedule 21.10.2014
comment
Попробуйте явно преобразовать SurfaceMesh в GeoMesh<fvMesh> при инициализации surfaceVectorField.   -  person Ashalynd    schedule 21.10.2014
comment
Вы наследуете его в частном порядке? Если да, он не может получить доступ к базе в вызове функции   -  person Kostya    schedule 21.10.2014
comment
@Kostya: Нет, например, объявление surfaceMesh начинается так: class surfaceMesh : public GeoMesh<fvMesh>   -  person hertzsprung    schedule 21.10.2014
comment
Можете ли вы сделать функцию шаблоном? template <typename T> void foo(GeometricField<vector, fvsPatchField, T>& field) { ... }   -  person cdhowie    schedule 21.10.2014


Ответы (1)


Основная проблема в вашем объявлении функции заключается в том, что тип аргумента не может быть разрешен. Это означает, что спецификацию класса шаблона нельзя вывести, если вы укажете базовый класс в качестве параметра шаблона.

Аргумент, который вы надеетесь принять, — это экземпляр класса шаблона GeometricField. Кроме того, имя шаблона класса не является типом. Указывает, что определение функции foo(GeometricField& field); невозможно.

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

template <typename T>
void foo(GeometricField<vector, fvsPatchField, T>& field) {}

или просто

template <typename T>
void foo(T& field) {}

который когда-либо лучше подходит для того, что вы делаете в функции. Заметьте также, что если функция будет использоваться повторно, вам нужно позаботиться о случаях, когда аргумент не соответствует вашим ожиданиям.

Перегрузка:

void foo(surfaceVectorField& field);
void foo(volVectorField& field);

Оба решения должны привести вас туда.

person PekkaRo    schedule 18.12.2014