如果type是引用,则行为不同

时间:2018-06-05 07:02:59

标签: c++ reference template-meta-programming boost-any boost-optional

我在项目中经常使用函数tryValue。它是boost::any的简单包装,大大简化了日常使用。

#include <boost/optional.hpp>
#include <boost/any.hpp>
#include <boost/optional/optional_io.hpp>
#include <iostream>

template<typename T>
boost::optional<T> tryValue(const boost::any& any) {
    try {
        boost::optional<T> ret(boost::any_cast<T>(any));
        return ret;
    }
    catch (...) {
    }
    return boost::none;
}

template<typename T>
boost::optional<T> tryValueRef(boost::any& any) {
    try {
        boost::optional<T> ret(boost::any_cast<T>(any));
        return ret;
    }
    catch (...) {
    }
    return boost::none;
}

int main(int, char**) {
    boost::any x(5);
    auto u = tryValue<int>(x);
    u = 6;
    std::cout << boost::any_cast<int>(x) << std::endl;

    auto r = tryValueRef<int&>(x);
    *r = 8; // Here I need a *? Why is that?
    std::cout << boost::any_cast<int>(x) << std::endl;
}

现在,我扩展了这个功能,以便我可以处理参考。这样就有机会更改boost-optional内的值。

如果我必须写tryValuetryValueRef,请记住这一点很烦人。函数tryValue应该自己弄清楚,T是否是引用(甚至是指针)。模板函数std::is_reference<T>应该完成这项工作,但我不知道如何有效地使用它。

第二部分,我还不了解,为tryValueRef的返回值需要额外*来设置值。

解决方案

简单地重命名该功能就足以使其发挥作用。

template<typename T>
boost::optional<T> tryValue(const boost::any& any) {
    try {
        boost::optional<T> ret(boost::any_cast<T>(any));
        return ret;
    }
    catch (...) {
    }
    return boost::none;
}

template<typename T>
boost::optional<T> tryValue(boost::any& any) {
    try {
        boost::optional<T> ret(boost::any_cast<T>(any));
        return ret;
    }
    catch (...) {
    }
    return boost::none;
}

int main(int, char**) {
    boost::any x(5);
    auto u = tryValue<int>(x);
    u = 6;
    std::cout << boost::any_cast<int>(x) << std::endl;

    auto v = tryValue<int&>(x);
    *v = 7;
    std::cout << boost::any_cast<int>(x) << std::endl;
}

0 个答案:

没有答案