Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template definition can't find my function

I'm trying to port some code written for MSVC over to compile on Clang. However it seems to be having a problem finding some template functions. Here is part of the definition of the struct that is giving me problems:

template< typename T > struct FixedVector
{
    T * ptr;
    size_t count;

    typedef T value_type;

    FixedVector():ptr(0),count(0) {}
    ~FixedVector()
    {
        DeleteArr(ptr); // Error message appears here
        count=0;
    }
// ...
}

The DeleteArr(ptr) function refers to a function defined later on, like so:

template< typename T > inline void DeleteArr( T *& ptr )
{
    delete[] ptr;
    ptr = NULL;
}

This is the error message I get on the line indicated:

error: call to function 'DeleteArr' that is neither visible in the template definition nor found by argument-dependent lookup

Looking at the full drop-down list for the error (in Xcode), the following message is at the bottom of the list:

'DeleteArr' should be declared prior to the call site or in an associated namespace of one of its arguments.

Clicking on this message brings me to the definition of the DeleteArr() function, as shown above.

This apparently compiled fine in MSVC, and from looking around at the differences between Clang and MSVC, this is due to a quirk in MSVC that doesn't require functions like this to be defined before they're used, as long as there is a definition somewhere. So I looked up this error message in the Clang documentation (relevant part is under the title "Unqualified lookup in templates") and it suggested adding a forward declaration before the template definition. So I added this above the definition for FixedVector:

template< typename T > inline void DeleteArr( T *& ptr );

However, this error message is still coming up, and that final bit of the error message (the 'should be declared prior to the call site' bit) still points to the actual definition of the function. Does anyone know what may be the problem? I'm all out of ideas as to how this is valid on MSVC. Also, since the error message can find the definition of the function, why is it saying it can't be found?

UPDATE: At the advice of the comments, I've added the implementation of DeleteArr() to where I declared it above the template. This seems to result in the same error! I'm really stumped now.

like image 231
benwad Avatar asked Sep 26 '12 09:09

benwad


2 Answers

The declaration of DeleteArr must be available to FixedVector, i.e. the definition of the former has to come before the use by the latter. This is likely related to the failure of MSVC to correctly implement the two-phase lookup.

like image 102
juanchopanza Avatar answered Sep 20 '22 10:09

juanchopanza


first define DeleteArr

template< typename T > inline void DeleteArr( T *& ptr )
    {
        delete[] ptr;
        ptr = NULL;
    }

Then define fixedvector

template< typename T > struct FixedVector
{
    T * ptr;
    size_t count;

    typedef T value_type;

    FixedVector():ptr(0),count(0) {}
    ~FixedVector()
    {
        DeleteArr(ptr); // Error message appears here
        count=0;
    }
// ...
}
like image 35
Ravindra Bagale Avatar answered Sep 21 '22 10:09

Ravindra Bagale