Подтвердить что ты не робот

G++, clang++ и std:: function

Я просто играл с новой std:: функцией из С++ 11, и я написал пример, который компилируется с clang++ 3.2 и компилятором Intel С++ 13.1, но не с g++ 4.8. Прежде чем сообщить об этом как об ошибке, я подумал, что проверю, что я не делаю что-то действительно глупое, и что это должно скомпилировать. Итак, следующий код действителен С++ 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;
    }
}

Я понимаю, что этот код не очень полезен, но это показалось мне странным, что clang и Intel С++ скомпилировали его, а gcc не сделали.

EDIT: gcc также не будет компилировать тот же код при прохождении карты как функтор или указатель функции:

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

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

clang и icpc также скомпилируют оба из них.

4b9b3361

Ответ 1

Это ошибка g++, ее можно свести к следующему примеру, который не использует std::function (или что-нибудь из стандартной библиотеки):

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);
}

Я сообщил об этом bugzilla как PR 56874. Проблема не связана с lambdas, а с типом в невыводимом контексте, который неправильно вызывает отклонение аргумента.