10

C++ 11 の新しい std::function をいじっていたところ、g++ 4.8 ではなく、clang++ 3.2 およびインテル C++ コンパイラー 13.1 でコンパイルされる例を作成しました。これをバグとして報告する前に、本当にばかげたことをしていないことと、これが実際にコンパイルされることを確認しようと思いました。では、次のコードは有効な 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;
    }
}

このコードがあまり役に立たないことはわかっていますが、clang と Intel C++ がコンパイルし、gcc がコンパイルしなかったことは奇妙に思えました。

編集: 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 もこれらの両方をコンパイルします。

4

1 に答える 1

10

これは 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);
}

PR 56874として bugzilla に報告しました。この問題はラムダとは関係ありませんが、推定されないコンテキストの型が原因で、引数の推定が失敗します。

于 2013-04-08T11:53:16.117 に答える