【问题标题】:Lambda not found when defined in an inline function in G++ 4.7在 G++ 4.7 的内联函数中定义时找不到 Lambda
【发布时间】:2012-10-24 03:19:25
【问题描述】:

我在头文件中定义了以下函数(它所在的库旨在仅作为头文件):

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 在内联函数中,因此它们应该在任何使用该函数的翻译单元中定义。

-- 编辑--

还有一点值得注意:示例程序中没有使用SearchGetComparer 函数。

Search 用于Table&lt;Description&gt; 的成员函数中(我无法发布完整的课程):

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 类型擦除类的一部分)。

【问题讨论】:

  • 其他人在 C++ 休息室发布的示例:liveworkspace.org/code/35374b3c9b0d40e8ccc0819eb44d7f9e
  • @J.N 你试过删除inline吗?这似乎解决了 liveworkspace 链接上的问题。不过,您似乎发现了一个编译器错误。
  • @J.N. LucDanton 在 C++ 休息室中提到,将函数更改为内部链接可以解决问题,至少如果你这样做,它seems to compile。也许这对你来说是一个选择?
  • @Praetorian 完全解决了问题,对我来说可以接受。使用匿名命名空间也可以(不出所料)。

标签: c++ c++11 gcc4.7


【解决方案1】:

bug report 已提交给 GCC 团队,其中一位开发人员拥有confirmed the issue on trunk

同时,正如 LucDanton 在聊天中指出的那样,声明函数 static 将解决问题。

【讨论】:

    猜你喜欢
    • 2011-12-13
    • 1970-01-01
    • 2014-08-29
    • 2012-10-15
    • 2021-04-05
    • 1970-01-01
    • 2019-11-23
    • 2013-06-04
    • 1970-01-01
    相关资源
    最近更新 更多