Я конвертирую свой проект наследия VC++ в совместимость с Android NDK, и я получаю странную ошибку. В сообщении говорится:
[armeabi] Compile++ thumb: procalc-core <= pcc_arithmetics.cpp
In file included from D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_arithmetics.h:10:0,
from D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_arithmetics.cpp:1:
D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_common.h: In static member function
'static std::string ProCalcCore::CommonTools::ToStringBase(T, int)':
D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_common.h:102:68: error: there are no
arguments to 'ConvertException' that depend on a template parameter, so a
declaration of 'ConvertException' must be available [-fpermissive]
throw ConvertException(PROCALC_ERROR_SYNTAX_INVALID_INTEGER_BASE);
^
D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_common.h:102:68: note: (if you use
'-fpermissive', G++ will accept your code, but allowing the use of an undeclared
name is deprecated)
make.exe: *** [D:/Dokumenty/Dev/Android/ProCalc//obj/local/armeabi/objs/procalc-
core/pcc_arithmetics.o] Error 1
Ошибка помещается в следующее место:
template <typename T>
std::string CommonTools::ToStringBase(T val, int base)
{
if (base < 2)
throw ConvertException(PROCALC_ERROR_SYNTAX_INVALID_INTEGER_BASE);
Значение, указанное в #define
шапки, является значением #define
d int.
ConvertException
объявляется в другом файле:
namespace ProCalcCore
{
(...)
class ConvertException : public InternalException
{
public:
ConvertException(const unsigned long int & newErrorCode);
};
Когда я пытаюсь изменить ConvertException
на ProCalcCore::ConvertException
, я получаю еще одну ошибку:
D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_common.h:102:10: error: 'ConvertException'
is not a member of 'ProCalcCore'
Все зависимости решаются правильно - в VS проект компилируется без проблем.
Как я могу это решить? Что вызывает эту ошибку?
"В визуальной студии проект компилируется без проблем" является слабым доказательством правильности ваших зависимостей.
Проблема заключается в том, что ConvertException
не отображается в точке, где объявлен template
. Некоторые версии Visual Studio только пытаются связать такие "свободные" типы и выражения в точке, где создается экземпляр template
, что неверно в соответствии со стандартом C++.
Поэтому ваш компилятор указывает, что он не может решить, к какому типу относится ConvertException
. Чтобы он знал, к какому типу относится, вам нужно либо переслать объявление (которое может иметь свои проблемы), либо #include
заголовочный файл до его использования.
Если вы считаете, что уже используете #include
, часто ваша проблема заключается в том, что заголовочный файл, содержащий ConvertException
заканчивается #include
CommonTools::ToStringBase
. Защитные файлы заголовка (или #pragma once
), затем устраняют бесконечный цикл.
Раздражающе, как исключается бесконечный цикл, зависит от того, какой заголовочный файл вы включаете первым! Если вы включаете заголовочный файл ConvertException
, он включает ToStringBase
, который включает в себя ConvertException
. Этот второй #include "ConvertException.h"
устраняется #include "ConvertException.h"
header-file #define
.
Если вместо этого вы включили ToStringBase
, это будет включать в себя ConvertException
, которое затем включает ToStringBase
, которое устраняется ConvertException
заголовков.
Таким образом, какой бы заголовок не был включен, сначала заканчивается разбор второй.