2
我在一個頭文件中定義了一個函數模板,並在幾個源文件中使用它。當我鏈接程序時,出現以下錯誤:內聯函數在鏈接過程中碰撞?
Linking ....................... ./Release_gcc_lin64_5534_ST/tom
/mxhome/charrison/git/sdcore/libs/CommUtils/Release_gcc_lin64_5534_ST/libCommUtils.so(Block.o): In function `wd_sprintf_r(boost::basic_format<char, std::char_traits<char>, std::allocator<char> > const&)':
/mxhome/charrison/git/sdcore/libs/CommUtils/include/wd_sprintf.h:29: multiple definition of `wd_sprintf_r(boost::basic_format<char, std::char_traits<char>, std::allocator<char> > const&)'
./Release_gcc_lin64_5534_ST/tom.o:/mxhome/charrison/git/sdcore/libs/CommUtils/include/wd_sprintf.h:29: first defined here
/mxhome/charrison/git/sdcore/libs/CommUtils/Release_gcc_lin64_5534_ST/libCommUtils.so(MemRef.o): In function `wd_sprintf_r(boost::basic_format<char, std::char_traits<char>, std::allocator<char> > const&)':
/mxhome/charrison/git/sdcore/libs/CommUtils/include/wd_sprintf.h:29: multiple definition of `wd_sprintf_r(boost::basic_format<char, std::char_traits<char>, std::allocator<char> > const&)'
./Release_gcc_lin64_5534_ST/tom.o:/mxhome/charrison/git/sdcore/libs/CommUtils/include/wd_sprintf.h:29: first defined here
我不明白髮生了什麼事。假設這些函數正在內聯,那麼如何防止跨目標文件的多個實例發生衝突?
這裏是包含函數定義的頭文件:
wd_sprintf.h:
#ifndef WDSPRINTF_H
#define WDSPRINTF_H
#include <string>
#include <sstream>
#include <boost/format.hpp>
// This is what the recursive template function wd_sprintf_r devolves
// to..
std::string
wd_sprintf_r(const boost::format &boost_format) {
std::stringstream s;
s << boost_format;
return std::move(s.str()); // force move semantics
}
// wd_sprintf_r(format, args...):
//
// This unpacks the variadic arguments one at a time, recursively. It
// binds the first arg to the pattern, and if there are remaining
// variadic arguments, it calls itself. Otherwise it calls the above.
template <typename T, typename... Params>
std::string
wd_sprintf_r(boost::format &boost_format,
const T &arg, const Params&... parameters) {
return wd_sprintf_r(boost_format % arg, parameters...);
}
// wd_sprintf(pattern [,args...]):
//
// This creates a temporary boost::format from pattern, and calls
// wd_sprintf_r() to recursively extract and apply arguments.
#include <boost/exception/all.hpp>
class wd_sprintf_exception : public std::runtime_error {
public:
wd_sprintf_exception(std::string const& msg) : std::runtime_error(msg) {};
};
template <typename... Params>
std::string
wd_sprintf (const std::string &pat, const Params&... parameters) {
try {
boost::format boost_format(pat);
return wd_sprintf_r(boost_format, parameters...);
}
catch (boost::io::format_error& e) {
const std::string what = std::string("wd_sprintf: ") + std::string(e.what());
throw wd_sprintf_exception(what);
}
}
#endif
問題是非模板過載。標記爲「inline」。 – jrok