2016-06-03 4 views
2

내 프로젝트 중 하나에서 활발하게 boost::variant을 사용하고 있으며 혼자 해결할 수없는 질문을 발견했습니다. 원자 데이터 유형 및 이러한 원자 데이터 유형의 STL 컨테이너를 포함 할 수있는 boost::variant이 있습니다.가변 인수 템플릿을 사용하는 Boost 변형 방문자

이제는 이전에 정의한 boost::variant 유형의 인스턴스 크기를 계산하고 싶습니다. 기본적으로 가능한 기능은 두 가지뿐입니다. 원자 데이터 유형의 유형은 간단히 1이지만 STL 컨테이너의 크기는 포함 된 요소의 수로 정의됩니다. 내가 코드 중복을 많이 가지고 원자 데이터 유형의 수가 증가로

#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; 
} 

:

는 2 원자 dataypes를 갖는 다음 코드를 구현했습니다. 새로운 원자 데이터 유형마다 또 다른 두 가지 함수를 선언해야합니다. 이는 금지 될 수 있습니다.

다음 코드를 컴파일한다면 그것은 좋은 것 :

#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; 
} 

은 무엇 두 번째의 가장 가까운 구현, 불행하게도 비 컴파일, 방문자 수 있습니다?

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(); 
    }  
}; 

템플릿 부분 순서 규칙이 올바른가 호출되어 있는지 확인합니다 :

답변

5

그냥 operator() 두 가지 기능 템플릿을 사용하십시오.

+0

와우. 그것은 매우 분명한 해결책입니다. 많은 감사합니다. 더 일반적인 문제에 대한 해결책이 있는지 궁금합니다. 주어진'boost :: variant' 유형 집합을 두 개의 하위 집합으로 나누어야합니다. 숫자 및 비 숫자로 변환합니다. 그리고이 속성에 대한 부울을 생성하는 방문자를 작성하려고했습니다. – Aleph0

+0

@FrankSimon SFINAE를 사용하십시오 - 하나의 과부하가 활성화되어 있고 하나는 일부 유형 특성에 따라 비활성화되어 있습니다. – Barry

+0

나는 그 개념을 알지 못한다. C++에 대해 좀 더 배워야한다고 생각합니다. 이러한 깊은 통찰에 대해 많은 감사드립니다. 나는 그것을 살펴볼 것이다. – Aleph0

관련 문제