【问题标题】:C++11 g++ strangeness (using defaulted template, lambda & remove_if)C++11 g++ 奇怪(使用默认模板、lambda 和 remove_if)
【发布时间】:2014-02-16 16:01:28
【问题描述】:

我遇到了一些非常奇怪的 g++ 行为,希望能得到一些帮助。 所以我想展示三个几乎相似的代码:

class Foo 
{
    public:

    template<typename T = char>
    bool Moo(std::function<bool()> f = [](){ return true; }) const
    {
        std::string str2 = "Text\n with\tsome \t  whitespaces\n\n";
        str2.erase(std::remove_if(str2.begin(), str2.end(),
                        [](char x){return true;}), str2.end());
        // just to do something
        f = 0;
        return f();
    };
};

int main(int argc, char **args) 
{
    Foo* myFoo = new Foo();
    return myFoo->Moo<>();
}

这将产生 3 个错误:

  • 包含'Foo::Moo(std::function) const::__lambda1' [](char x){return true;})的类的模板参数的默认参数
  • 没有匹配的函数调用‘Foo::Moo()’
  • 模板参数推导/替换失败

现在,如果我们将 Moo 的参数更改为普通类型 ,如果我们取出函数体内的 lambda(通过用“str.erase”取出整行),代码编译没有错误!

将参数改为普通类型:

class Foo 
{
    public:

    template<typename T = char>
    bool Moo(bool f = true) const
    {
        std::string str2 = "Text\n with\tsome \t  whitespaces\n\n";
        str2.erase(std::remove_if(str2.begin(), str2.end(),
                        [](char x){return true;}), str2.end());
        // just to do something
        f = 0;
        return f;
    };
};

int main(int argc, char **args) 
{
    Foo* myFoo = new Foo();
    return myFoo->Moo<>();
}

删除带有“str.erase”的行:

class Foo 
{
    public:

    template<typename T = char>
    bool Moo(std::function<bool()> f = [](){ return true; }) const
    {
        std::string str2 = "Text\n with\tsome \t  whitespaces\n\n";
        // just to do something
        f = 0;
        return f();
    };
};

int main(int argc, char **args) 
{
    Foo* myFoo = new Foo();
    return myFoo->Moo<>();
}

那么这里发生了什么?为什么函数体(“str.erase”行)中的“remove_if-lambda”和函数参数列表中的“defaulted-lambda function”的组合会产生函数头中“defaulted template parameter”的错误?

【问题讨论】:

  • 您使用的是哪个版本的 g++? IIRC 存在与 lambdas 作为默认参数相关的错误..
  • clang++3.5 trunk 198621上编译良好(并且“按预期”工作)
  • 我一直在使用 g++ 4.8.1,但我看到现在有 4.8.2,所以我也要试试,让你知道。
  • @BM 在 g++ 4.9 中也没有修复。
  • 没有用 clang 尝试过,所以如果 g++4.9 仍然失败,那么我想我们这里有一个官方错误

标签: c++ templates c++11 lambda


【解决方案1】:

所以我可以关闭问题并确认问题:

上述(第一个)代码示例无法在 g++-4.8.1、g++-4.8.2 和 g++-4.9 上编译。 它确实在 clang++ 3.2-7ubuntu1 上编译。因此,由于没有看到任何语法错误,我将此称为 gcc 中的错误。

我已将该错误报告为错误 59944:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59944

编辑: 此后此错误已在 gcc 4.9.2 中修复

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-04
    • 2014-06-30
    • 2015-03-08
    • 1970-01-01
    • 2017-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多