I am using Visual Studio 2008. I am getting the a linker error when building a project that contains a statically linked library only when using MFC CString (vs std::wstring).
So this works:
//header
class FileProcessor
{
public:
class iterator;
friend class iterator;
//...
class iterator : public std::iterator<std::input_iterator_tag, std::vector<std::vector<std::wstring>>>
{
public:
//...
std::vector<std::vector<std::wstring>> operator*() const;
}
}
//cpp
std::vector<std::vector<std::wstring>> FileProcessor::iterator::operator*() const
{
return _outerRef->_pimpl->_saxHandler->GetCurrentTable();
}
But this
//header
#include <afx.h>
class FileProcessor
{
public:
class iterator;
friend class iterator;
//...
class iterator : public std::iterator<std::input_iterator_tag, std::vector<std::vector<CString>>>
{
public:
//...
std::vector<std::vector<CString>> operator*() const;
}
}
//cpp
std::vector<std::vector<CString>> FileProcessor::iterator::operator*() const
{
return _outerRef->_pimpl->_saxHandler->GetCurrentTable();
}
gives the linker error:
FileProcessingTests.obj : error LNK2019: unresolved external symbol "public: class
std::vector<class std::vector<class std::basic_string<wchar_t,struct
std::char_traits<wchar_t>,class std::allocator<wchar_t> >,class std::allocator<class
std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class
std::allocator<wchar_t> > > >,class std::allocator<class std::vector<class
std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class
std::allocator<wchar_t> >,class std::allocator<class std::basic_string<wchar_t,struct
std::char_traits<wchar_t>,class std::allocator<wchar_t> > > > > > __thiscall
FileProcessing::FileProcessor::iterator::operator*(void)const "
(??Diterator@FileProcessor@FileProcessing@@QBE?AV?$vector@V?$vector@V?$basic_string@_WU?
$char_traits@_W@std@@V?$allocator@_W@2@@std@@V?$allocator@V?$basic_string@_WU?$char_traits
@_W@std@@V?$allocator@_W@2@@std@@@2@@std@@V?$allocator@V?$vector@V?$basic_string@_WU?$
char_traits@_W@std@@V?$allocator@_W@2@@std@@V?$allocator@V?$basic_string@_WU?$char_traits
@_W@std@@V?$allocator@_W@2@@std@@@2@@std@@@2@@std@@XZ) referenced in function "void
__cdecl TestUnicodeSingleTable(void)" (?TestUnicodeSingleTable@@YAXXZ)
In both projects, the calling convention is specified as __cdecl
in the project file. So why is __thiscall
even arising, and how can I fix it? I have to use __cdecl
because I am referencing external libraries that use __cdecl
.
Additional project settings:
Both projects have these configuration settings:
It looks like FileProcessingTests.cpp
isn't being rebuilt or it's using a stale header. That object file is still trying to link to the std::wstring
variant rather than the CString
variant.
The error message is a verbose way of saying that the unresolved external symbol is for:
std::vector<std::vector<std::wstring>> FileProcessor::iterator::operator*() const
Keep in mind that std::wstring
is just a typedef for:
class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >
if you make the default template parameters explicit. The error message is also making the default template parameters for std::vector
explicit as well, which is why the error message has such horrendous spew.