Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

G++, clang++ and std::function

I was just playing around with the new std::function from C++11, and I wrote an example that compiles with clang++ 3.2 and the Intel C++ compiler 13.1 but not with g++ 4.8. Before I report this as a bug, I thought I'd check that I'm not doing something really stupid and that this should actually compile. So, is the following code valid c++11?

template <typename C>
void map(C& c, std::function<typename C::value_type(typename C::value_type)> f)
{
    for(auto& x : c) {
        x = f(x);
    }
}

int main()
{
    std::vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    map(v, [](int x) { return x+2; });

    for(auto x : v) {
        std::cout << x << std::endl;
    }
}

I realise that this code isn't very useful but it struck me as odd that clang and Intel C++ compiled it and gcc didn't.

EDIT: gcc will also not compile the same code when passing map a functor or function pointer:

struct {
    int operator() (int a) {
        return a+2;
    }
} add2s;
map(v, add2s);

int add2 (int a) {
    return a+2;
}
map(v,add2);

clang and icpc also compile both of these.

like image 983
dtruby Avatar asked Apr 08 '13 10:04

dtruby


1 Answers

This is a G++ bug, it can be reduced to the following example which doesn't use std::function (or anything from the standard library):

template<typename T>
struct function
{
    function(int)
    { }
};

struct V {
  typedef int value_type;
};

template <typename C>
void map(C&, function<typename C::value_type>)
{
}

int main()
{
  V v;
  map(v, 1);
}

I've reported it to bugzilla as PR 56874. The problem is not related to lambdas, but to a type in a non-deduced context incorrectly causing argument deduction to fail.

like image 112
Jonathan Wakely Avatar answered Nov 13 '22 15:11

Jonathan Wakely