这个访客实现是否正确?

时间:2014-11-06 15:27:12

标签: c++ boost boost-variant static-visitor

我正在实施访问者,以便将其与提升变体库一起使用。 我想知道使用const引用类型专门化boost::static_visitor<>是否正确。

请注意我的问题如下:

boost::static_visitor<>boost::static_visitor<const T&>有什么问题?

template<typename T>
struct my_visitor : public boost::static_visitor<const T&> {

    template<typename U> const T& operator()(U& u) const {
        // some code here .....
        return X<U>::get_some_t(); // finally return some T.
    }
};

1 个答案:

答案 0 :(得分:2)

只要您不返回对本地/临时的引用,就没有问题。

另外,请务必检查参考值的有效性(当变体对象被破坏时结束,即变体本身被破坏时, (!)重新初始化时。)

背景和解释

变体包含&#34;当前&#34;的对象。元素类型,您可以引用到该对象完全正常。 只要该变体不会重新初始化为另一种元素类型(在这种情况下,引用是&#34;只是&#34;悬空,就像引用对象的生命周期一样结束)。

因此,如果get_somet_t()返回T&T const&(或具有适当隐式转化的内容),则没有问题。

在更简单的设置中,让我演示有效的选项:

variant<int, std::string> v1 = 42;

int& i1 = get<int>(v1); // returns by ref, valid
i1 *= 2;

// now v1 contains the updated integer value 84

同样,您甚至可以制作/仅引用/:

的变体
std::string s = "hello";
int answer = 42;

variant<int&, std::string&> v2(s);
get<std::string&>(v2) += " world"; // now s contains "hello world"

variant<int&, std::string&> v3(answer);
get<int&>(v3) *= 2; // now `answer` contains 84

全部查看 Live On Coliru


示范

以另一种方式,以下情况很好:

struct A { std::string a_property; };
struct B { std::string b_field;    };

struct select_member : static_visitor<std::string&> {
    std::string& operator()(A& a) const { return a.a_property; }
    std::string& operator()(B& b) const { return b.b_field;    }
};

int main()
{
    variant<A,B> v = A { "some string" };

    apply_visitor(select_member(), v) += " suffix";

    std::cout << get<A>(v).a_property << "\n"; // prints "some string suffix"
}

同时查看 Live On Coliru