在Visual Studio 2010中了解此错误(LNK 2019)

时间:2012-10-10 20:31:11

标签: c++ visual-studio-2010

好的,所以我正在研究一个C ++项目,我无法弄清楚如何缓解这个链接器错误。它在下面:

  

1> test4.obj:错误LNK2019:未解析的外部符号“private:bool __thiscall OrderedList :: binarySearch(char,int&)”(?binarySearch @?$ OrderedList @ VRecord @@ D @@ AAE_NDAAH @ Z)在函数“public:virtual void __thiscall OrderedList :: insert(class Record const&)”中引用(?insert @?$ OrderedList @ VRecord @@ D @@ UAEXABVRecord @@@ Z)

如果有人可以帮助分解并向我翻译Visual Studio 2010所说的那将是惊人的(我真的想要更好地阅读输出)。我一直在阅读这个特殊的错误,但我仍然不明白为什么它适用于我的代码。

编辑:binarySearch方法正在OrderedList.cpp文件中实现。我也在包含我的main的文件中使用#include“OrderedList.cpp”语句。

有问题的两个功能:

插入原型:

virtual void insert ( const DataType &newDataItem ) throw ( logic_error );

插入:

template <typename DataType, typename KeyType>
void OrderedList<DataType, KeyType>::insert(const DataType &newDataItem) 
throw (logic_error ) {
int index = 0;
if (size == maxSize) {
    throw logic_error("List is full.");
} 
else { 
    KeyType searchKey = newDataItem.getKey();
    if (binarySearch(searchKey, index)) {
        cursor = index;
        dataItems[cursor] = newDataItem;
    }
    else {
        cursor = index;
        insert(newDataItem);
    }
} 
}

二进制搜索原型:

bool binarySearch ( KeyType searchKey, int &index );

二进制搜索:

template < typename DataType, typename KeyType >
bool binarySearch (KeyType searchKey, int &index ) {
int low  = 0;        // Low index of current search range
int high = size - 1;    // High index of current search range
bool result;            // Result returned

while ( low <= high )
{
    index = ( low + high ) / 2;               // Compute midpoint
    if ( searchKey < dataItems[index].getKey() )
       high = index - 1;                      // Search lower half
    else if ( searchKey > dataItems[index].getKey() )
       low = index + 1;                       // Search upper half
    else
       break;                                 // searchKey found
}

if ( low <= high )
   result = true;       // searchKey found
else
{
   index = high;        // searchKey not found, adjust index
   result = false;
}

return result;
}

另外,Record类:

class Record
{
public: 
Record () { key = char(0); }
void setKey(char newKey) { key = newKey; }
char getKey() const { return key; }

private:
char key;

};

3 个答案:

答案 0 :(得分:1)

模板函数在用适当的模板参数调用之前不是真正的函数。在这种情况下,由于OrderedList.cpp文件没有包含对函数的调用,因此从未生成实际的函数代码。这就是链接器无法找到它的原因。

通常在头文件中定义模板函数或类以避免此问题。

答案 1 :(得分:1)

行是否可能:

template < typename DataType, typename KeyType >
bool binarySearch (KeyType searchKey, int &index )

在您的cpp文件中,您只是忘记将其实现为:

template < typename DataType, typename KeyType >
bool OrderedList<DataType, KeyType>::binarySearch(KeyType searchKey, int &index)

然后binarySearch只是一个全局函数而不是来自OrderedList的函数,并且尝试查找OrderedList<DataType, KeyType>::binarySearch的链接器不将其视为指定函数??!

答案 2 :(得分:1)

让我们逐行打破这个:

1>test4.obj : error LNK2019: unresolved external symbol 

这告诉你,在test4.obj文件中,编译器无法找到它期望可用的编译对象。

"private: bool __thiscall OrderedList::binarySearch(char,int &)" 

这是它无法找到的对象(在这种情况下是成员函数)的函数签名。

(?binarySearch@?    $OrderedList@VRecord@@D@@AAE_NDAAH@Z) 

这是上述函数的“受损名称” - 编译器在目标文件中给出的名称。它为编译器提供了一种文本方式,用于验证具有相似名称但不同类型关联的对象。

referenced in function 

这一行告诉您下一个对象将是引用未解析符号的位置。

"public: virtual void __thiscall OrderedList::insert(class Record const &)"

这是调用导致错误的符号的对象的函数签名。请注意,模板参数在此处不可见,但任何类型绑定的参数都是,因此您知道DataType的类型为Record,但您不知道KeyType是什么。< / p>

(?insert@?$OrderedList@VRecord@@D@@UAEXABVRecord@@@Z)

这是上述函数的错位名称。


现在,让我们来看看这意味着什么。您有一个模板方法,它调用看似全局的函数模板。该全局函数模板有两个模板参数,其中只有一个是通过调用函数提供的。

换句话说,您没有提供DataType,因此编译器不知道如何生成函数模板binarySearch的模板特化。

这里的好消息是你实际上并不需要DataType模板参数,所以你应该可以简单地消除它。此时,您的函数模板将完全专业化并且应该编译。