1

メンバーへのポインターを使用してオブジェクトのフィールドへの読み取り専用アクセスを取得しようとしていますが、「アクセス違反の読み取り場所...」エラーが発生します。

template<typename X, typename Y>
class a
{
public:
    a(Y X::*field): f([&](const X &x) { return x.*field; }) {} // error
    a(Y (X::*method)() const): f([=](const X &x) { return (x.*method)(); }) {}
    a(std::function<Y(const X &)> f): f(f) {}

    Y operator()(const X &x) const { return f(x); }

private:
    std::function<Y(const X &)> f;
};

class X
{
public:
    X(): x(1) {}
    int x;
    int f() const { return x + 1; }
};

int main()
{
    X x;
    a<X const, int> a1(&X::x);
    a<X, int> a2(&X::f);
    a<X, int> a3([](const X &x) { return x.f() + x.x; });
    std::cout << a1(x) << a2(x) << a3(x) << std::endl;
    return 0;
}

フィールド定義に const 修飾子を追加しようとしましたが、役に立ちませんでした。

4

1 に答える 1

2

問題は、ラムダで物事をキャプチャする方法にあります。

a(Y X::*field): f([&](const X &x) { return x.*field; }) {}

fieldコンストラクタでのみ有効なへの参照を使用します。コンストラクターが終了すると、ダングリング参照が発生します。

修正する方法は、パラメータをコピーすることです:

a(Y X::*field): f([=](const X &x) { return x.*field; }) {}

a3適切なコンストラクターがないため、の作成は失敗します。

于 2013-11-12T16:32:14.080 に答える