我正在尝试将一些为MSVC编写的代码移植到Clang上进行编译。然而,它似乎在找到一些模板功能时遇到了问题。以下是给我提出问题的结构定义的一部分:
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;
}
// ...
}
DeleteArr(ptr)
函数指的是稍后定义的函数,如下所示:
template< typename T > inline void DeleteArr( T *& ptr )
{
delete[] ptr;
ptr = NULL;
}
这是我在指示的行上出现的错误消息:
error: call to function 'DeleteArr' that is neither visible in the template definition nor found by argument-dependent lookup
查看错误的完整下拉列表(在Xcode中),以下消息位于列表的底部:
'DeleteArr' should be declared prior to the call site or in an associated namespace of one of its arguments.
点击此消息,我将看到DeleteArr()函数的定义,如上所示。
这显然是在MSVC中编译好的,并且通过查看Clang和MSVC之间的差异,这是由于MSVC中的一个怪癖,它不需要在使用之前定义这样的函数,只要某处有一个定义。因此,我在Clang documentation中查找了此错误消息(相关部分位于“模板中的不合格查找”标题下),并建议在模板定义之前添加前向声明。所以我在FixedVector
的定义上面添加了这个:
template< typename T > inline void DeleteArr( T *& ptr );
但是,此错误消息仍然出现,并且错误消息的最后一位('应该在调用站点之前声明'位)仍然指向函数的实际定义。有谁知道可能是什么问题?我对MSVC的有效性一无所知。此外,由于错误消息可以找到函数的定义,为什么说它无法找到?
更新:根据评论的建议,我已将DeleteArr()的实现添加到我在模板上方声明的位置。这似乎导致了同样的错误!我现在真的很难过。
答案 0 :(得分:5)
DeleteArr
必须提供FixedVector
的声明,即前者的定义必须在后者使用之前。这可能与MSVC无法正确实现two-phase lookup。
答案 1 :(得分:1)
首先定义DeleteArr
template< typename T > inline void DeleteArr( T *& ptr )
{
delete[] ptr;
ptr = NULL;
}
然后定义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;
}
// ...
}