Reputation: 363
If I define a free function inside a named namespace inside a header file and that header file is included at multiple places, I get the linker error 2005 and LNK1169 in VS 2013.
one or more multiply defined symbols found
The build failed due to multiple definitions of one or more symbols. This error is preceded by error LNK2005.
If I make the namespace anonymous while keeping definition in header file, these linker errors do not happen.
Another option is to have named namespace but move definition of free function to a .cpp file and leave the declaration in the header file.
Why this behavior is seen? MSDN link given above is not very helpful.
Error : Definition inside named namespace in header.h
namespace estd
{
std::wstring tolower(std::wstring val){
std::transform(val.begin(), val.end(), val.begin(), ::towlower);
return val;
}
}
No Error 1 : Definition inside anonymous namespace in header.h
namespace
{
std::wstring tolower(std::wstring val){
std::transform(val.begin(), val.end(), val.begin(), ::towlower);
return val;
}
}
No Error 2 : Definition inside named namespace in header.cpp and declaration inside header.h
// header.h content
#pragma once
#include <string>
namespace estd
{
std::wstring tolower(std::wstring val);
}
// header.cpp content
#include "header.h"
#include <algorithm>
namespace estd
{
std::wstring tolower(std::wstring val){
std::transform(val.begin(), val.end(), val.begin(), ::towlower);
return val;
}
}
Upvotes: 1
Views: 1392
Reputation: 227370
Every translation unit that includes the header will have its own definition. Linking these together will result in multiple definitions. One way to avoid this while keeping the function definition in a header is to declare the function inline
.
namespace estd
{
inline std::wstring tolower(std::wstring val){
std::transform(val.begin(), val.end(), val.begin(), ::towlower);
return val;
}
}
Upvotes: 4