Spook
Spook

Reputation: 25927

How to resolve "There are no arguments to <name> depending on a template parameter"?

I'm converting my legacy VC++ project to be compatible with Android NDK and I'm getting a weird error. The message says:

[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

The error is thrown in the following place:

template <typename T>
std::string CommonTools::ToStringBase(T val, int base)
{
    if (base < 2)
        throw ConvertException(PROCALC_ERROR_SYNTAX_INVALID_INTEGER_BASE);

The caps-named error value is a #defined int value.

ConvertException is declared in another file:

namespace ProCalcCore
{
    (...)
    class ConvertException : public InternalException
    {
    public:
        ConvertException(const unsigned long int & newErrorCode);
    };

When I try to change ConvertException to ProCalcCore::ConvertException, I get another error:

D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_common.h:102:10: error: 'ConvertException' 
is not a member of 'ProCalcCore'

All dependencies are resolved correctly - in VS the project compiles without problems.

How can I solve it? What causes this error?

Upvotes: 0

Views: 253

Answers (1)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275730

"In visual studio the project compiles without problems" is weak evidence that your dependencies are correct.

The problem is that ConvertException is not visible at the point where the template is declared. Some versions of Visual Studio only try to bind such "free" types and expressions at the point where the template is instantiated, which is not correct under the C++ standard.

So your compiler is pointing out that it cannot work out what type ConvertException refers to. In order for it to know what type it refers to, you need to either forward declare it (which can have its own problems), or #include the header file prior to using it.

If you think you are already #includeing it, often your problem is that the header file that contains ConvertException ends up #includeing CommonTools::ToStringBase. The header file guards (or #pragma once) then eliminate the infinite loop.

Annoyingly, how the infinite loop is eliminated depends on which header file you include first! If you include the ConvertException header file, it then includes ToStringBase, which includes ConvertException back. That second #include "ConvertException.h" is eliminated by header-file #define guards.

If you instead included ToStringBase first, it would include ConvertException, which then includes ToStringBase, which is eliminated by the header guards.

So whatever header file is included first ends up being parsed second.

Upvotes: 1

Related Questions