代码之家  ›  专栏  ›  技术社区  ›  OneRaynyDay

如何绕过不支持3个参数的variant apply\u访问者?

  •  1
  • OneRaynyDay  · 技术社区  · 8 年前

    出于某种原因,使用boost的变体(我知道有一个c++17版本,我在这里提供向后兼容性,而且c++17还没有完全得到clang++的支持)会导致在使用visitor范式时出现一些奇怪的行为:

    2论据、作品

    #include <iostream>
    #include <boost/variant.hpp>
    
    using boost::variant;
    
    typedef boost::variant<double, std::string> term_t;
    
    class plus_visitor : public boost::static_visitor<term_t> {
    public:
        term_t operator()(double lhs, double rhs) const{
            return {lhs + rhs};
        }
        term_t operator()(double lhs, std::string rhs) const{
            return {lhs + std::stoi(rhs)};
        }
        term_t operator()(std::string lhs, int rhs) const{
            return operator()(rhs, lhs);
        }
        term_t operator()(std::string lhs, std::string rhs) const{
            return std::stoi(lhs) + std::stoi(rhs);
        }
    };
    
    int main(){
        // term_t lhs {3.0};
        term_t rhs {"10"};
        term_t lhs {"3"};
        term_t res = boost::apply_visitor(plus_visitor(), lhs, rhs);
        std::cout << res << std::endl;
        return 0;
    }
    

    #include <iostream>
    #include <boost/variant.hpp>
    
    using boost::variant;
    
    typedef boost::variant<double, std::string> term_t;
    
    class plus_visitor : public boost::static_visitor<term_t> {
    public:
        term_t operator()(double lhs, double rhs, double x) const{
            return {lhs + rhs + x};
        }
        term_t operator()(double lhs, std::string rhs, double x) const{
            return {lhs + std::stoi(rhs) + x};
        }
        term_t operator()(std::string lhs, double rhs, double x) const{
            return operator()(rhs, lhs, x);
        }
        term_t operator()(std::string lhs, std::string rhs, double x) const{
            return std::stoi(lhs) + std::stoi(rhs) + x;
        }
    };
    
    int main(){
        term_t rhs {"10"};
        term_t lhs {"3"};
        term_t x {3.0};
        term_t res = boost::apply_visitor(plus_visitor(), lhs, rhs, x);
        std::cout << res << std::endl;
        return 0;
    }
    

    这是怎么回事?做 apply_visitor 仅适用于2个参数?

    我查看了文档,发现:

    http://www.boost.org/doc/libs/1_36_0/doc/html/boost/apply_visitor.html

    应用访客 boost 允许更多输入的库函数?为什么boost库不使用可变模板来允许任意大小的 功能?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Praetorian Luchian Grigore    8 年前

    您正在查看Boost 1.36的文档,它是 released in 2008 . 如果你看看 documentation for the current release ,它列出了以下内容 apply_visitor 过载

    template<typename MultiVisitor, typename Variant1, typename Variant2, 
             typename Variant3> 
      typename MultiVisitor::result_type OR decltype(auto) 
      apply_visitor(MultiVisitor & visitor, Variant1 & operand1, 
                    Variant2 & operand2, Variant3 & operand3, ... other_operands);
    template<typename MultiVisitor, typename Variant1, typename Variant2, 
             typename Variant3> 
      typename MultiVisitor::result_type OR decltype(auto) 
      apply_visitor(const MultiVisitor & visitor, Variant1 & operand1, 
                    Variant2 & operand2, Variant3 & operand3, ... other_operands);
    

    这些函数实际上是在标题中定义的 boost/variant/multivisitors.hpp 如果要使用多个访问者,则必须手动包含该标题。

    operator() 3参数示例的重载,您的代码应该编译。