我在头文件中定义了以下函数(它所在的库旨在仅作为头文件):
typedef bool (*FieldComparer)(const std::string&, const std::string&);
inline FieldComparer
GetComparer(const std::string& query, string& separator)
{
if (query.find('=') != std::string::npos) {
separator = "=";
return [](const string& s1, const string& s2) { return s1 == s2; };
}
else if (query.find('^') != string::npos) {
separator = "^";
return [](const string& s1, const string& s2) { return boost::starts_with(s1, s2); };
}
else if (query.find('*') != string::npos) {
separator = "*";
return [](const string& s1, const string& s2) { return boost::contains(s1, s2); };
}
else if (query.find('!') != string::npos) {
separator = "!";
return [](const string& s1, const string& s2) { return s1 != s2; };
}
else
throw std::invalid_argument("Search: could not find operator in query string.");
}
template <class Description>
inline void
Search(Table<Description>& table, const std::string& query,
std::function<void(const std::string&)> callback, int begin, int limit)
{
string separator;
auto comparer = GetComparer(query, separator);
... do stuff with comparer ...
}
我正在尝试编译一个包含此文件的小型简单程序,但在链接时我得到了对所有 lambda 的未定义引用。当我说简单时,有一个 CPP 可以编译但无法链接。这是第一个错误:
obj/sample.o: In function `DataModel::GetComparer(std::string const&, std::string&)::{lambda(std::string const&, std::string const&)#1}::operator bool (*)(std::string const&, std::string const&)() const':
/home/julien/workspace_dma/src/DataModel/Search.h:23: undefined reference to `DataModel::GetComparer(std::string const&, std::string&)::{lambda(std::string const&, std::string const&)#1}::_FUN(std::string const&, std::string const&)'
自从我升级到 GCC 4.7.2 以来,它一直在发生,它曾经在 GCC 4.6.2 中运行良好(Ubuntu 版本以防万一)。虽然我知道解决问题的解决方法,但我想知道我做错了什么或没有正确理解。由于lambas 在内联函数内部,因此它们应该在使用该函数的任何翻译单元中定义。
- 编辑 -
还有一点值得注意:示例程序中没有使用Search
and函数。GetComparer
Search
用于Table<Description>
(我无法发布完整课程)的成员函数:
template <class Description>
void Table<Description>::Search(const std::string& query,
std::function<void(const std::string&)> callback, int begin, int count)
{
DataModel::Search(*this, query, callback, begin, count);
}
但两者都不是从 sample.cpp 文件中调用的。该文件测试其他Table
不相关的功能。如果我在成员中评论调用,代码会编译并链接。(我需要成员函数,它是虚拟的,它是上述类型擦除类的一部分Table
)。