使用可变参数模板参数增加变体访问者

Ale*_*ph0 2 c++ templates stl boost-variant boost-mpl

在我正在积极使用的一个项目中boost::variant,我偶然发现了一个我无法自行解决的问题.我有一个boost::variant可能包含原子数据类型和这些原子数据类型的STL容器.

现在,我想计算先前定义的boost::variant类型的实例的大小.基本上只有两种可能的功能.原子数据类型的类型只是1,而STL容器的大小定义为其中包含的元素数.

只有2个原子数据表我实现了以下代码:

#include <boost/variant.hpp>
#include <string>
#include <iostream>
#include <vector>

typedef boost::variant<int, double, std::vector<int>, std::vector<double> > TVariant;

struct sizeVisitor : boost::static_visitor<size_t> {
   size_t operator()(int&) {
    return 1;
    }
   size_t operator()(double&) {
    return 1;
    }

   size_t operator()(std::vector<int>& c) {
    return c.size();
    }

   size_t operator()(std::vector<double>& c) {
    return c.size();
    }
} ;


int main(int argc, char **args) {
    sizeVisitor visitor;
    TVariant var=5;
    std::cout << boost::apply_visitor(visitor, var) << std::endl;
    std::vector<int> vector;
    vector.push_back(6);
    vector.push_back(2);
    var=vector;
    std::cout << boost::apply_visitor(visitor, var) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

随着原子数据类型数量的增加,我有很多代码重复.我必须为每个新的原子数据类型声明另外两个函数,这可能是禁止的.

如果下面的代码可以编译,那就太好了:

#include <boost/variant.hpp>
#include <string>
#include <iostream>
#include <vector>

typedef boost::variant<int, double, std::vector<int>, std::vector<double> > TVariant;

struct sizeVisitor : boost::static_visitor<size_t> {
   size_t operator()(boost::variant<int,double>&) {
    return 1;
    }

   size_t operator()(boost::variant<std::vector<int>,std::vector<double>>& c) {
    return c.size();
    }

} ;


int main(int argc, char **args) {
    sizeVisitor visitor;
    TVariant var=5;
    std::cout << boost::apply_visitor(visitor, var) << std::endl;
    std::vector<int> vector;
    vector.push_back(6);
    vector.push_back(2);
    var=vector;
    std::cout << boost::apply_visitor(visitor, var) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

对于第二个,不幸的是非编译访问者,最接近的实现可能是什么?

Bar*_*rry 5

只需使用两个功能模板operator():

struct sizeVisitor 
    : boost::static_visitor<size_t>
{
    template <class T>
    size_t operator()(T const&) {
        return 1;
    }

    template <class T>
    size_t operator()(std::vector<T> const& v) {
        return v.size();
    }    
};
Run Code Online (Sandbox Code Playgroud)

模板部分排序规则将确保调用正确的规则.