2013-02-25 3 views
3

현재 읽고있는 일부 데이터에 대해 (다양한 위상 공간에서 정규화를 기반으로하는) 일련의 변수에 복잡한 변수 수정을 시도하고 있습니다. 수정은 동일한 프로세스를 따른다. 어쨌든 반복적으로이 변수를 처리하기보다는 (18-20 변수가 필요하기 때문에) 각 변수를 처리해야하는지 궁금하다. C++이 이것을 처리 할 수 ​​있습니까? 나는 파이썬에서 이것을 시도하는 누군가에 의해 들었다. 그러나 나는 C++에서 어떤 식 으로든 할 수있는 것처럼 느낀다 ... 나는 벽을 치고있다!클래스의 변수 멤버를 반복하는 방법 C++

class VariableClass{ 
    public : 
     //each object of this class represents an event for this particlular data set 
     //containing the following variables 
     double x; 
     double y; 
     double z; 
} 

내가의 라인을 따라 뭔가하고 싶은 :

당신이 생각처럼 주어진 일 부여하려면 어떤 조언을 사전에

for (int i=0; i < num_variables; i++) 
{ 
    for (int j=0; j < num_events; j++) 
    { 
    //iterate through events 
    } 
    //correct variable here, then move on to next one 
} 

감사합니다!

+2

배열과 같은 뜻입니까? – chris

+1

이것은 흥미로운 질문입니다. 나는 당신이 어떤 반응을 보일지 궁금해합니다. 변수 유형을 식별하는 데 어려움을 겪을 지 궁금합니다.예를 들어 메모리에있는 객체의 내용을 쉽게 볼 수 있지만 객체의 첫 번째 변수가 double인지 어떻게 알 수 있습니까? 나는이 질문에 대한 응답을 기대한다. – Kirby

+1

모든 변수가 두 배가됩니까? 번호가 고정되어 있습니까? 그런 다음'std :: array '또는 일반 old'double [18]'을 사용하십시오. – BatchyX

답변

1

예, 모든 변수를 컨테이너에 넣으십시오 (예 : std::vector).

+2

또는'std :: tuple' (유형이 다른 경우). – BatchyX

+0

네,하지만 여기에있는 것처럼 보이지 않습니까? – piokuc

+0

참고로, 저는 이것을 위해 벡터를 사용하는 방법을 생각하려고 했었습니다 ... 어떻게 구현할 것인가? 아마도 위에서 언급 한 것과 다른 방식으로 내 이벤트와 변수를 반복해야 할 것입니다. 그러나 단순히 벡터를 만드는 것이 더 까다 롭습니다. 아니면 어쩌면 내가 이것을 복잡하게 만들고있다 –

1

template <typename T> 
GLM_FUNC_QUALIFIER typename tvec3<T>::value_type & 
tvec3<T>::operator[] 
(
    size_type i 
) 
{ 
    assert(i < this->length()); 
    return (&x)[i]; 
} 

이 귀하의 예제로 번역하는 것 : 그냥 벡터 수학에 대한 경우

class VariableClass{ 
public : 
    //each object of this class represents an event for this particlular data 
    double x; 
    double y; 
    double z; 

    double & operator[](int i) { 
    assert(i < 3); 
    return (&x)[i]; 
    } 
} 

VariableClass foo(); 
foo.x = 2.0; 
std::cout << foo[0] << std::endl; // => 2.0 

Althought 난, GLM를 recomment 것이다.

+4

이것은 매우 안전하지 않습니다. 컴파일러가 데이터에 더 효율적으로 액세스 할 수 있도록 데이터를 채우지 않는다고 보장 할 수는 없습니다. 최소한이 버전에서는'#pragma pack (1)'또는 뭔가를 추가해야합니다. – Mic

+0

그것이 내가 도서관을 추천하는 이유입니다. 라이브러리가 테스트되었습니다. 그리고 나는'foo.x'를 통해 접근 할 필요가 있기 때문에 표준 컨테이너에 대한 대안으로 이것을 보여주고 있습니다. 네, 맞습니다. 안전하지 않습니다. – scones

0

일반적으로 다른 액세스 한정자가있는 섹션의 패딩이나 순서 변경과 같은 구현 정의에 의존하지 않고 멤버를 반복 할 수 없습니다. 컴파일러는 나중에 컴파일러가 없으므로 허용됩니다.

그러나 레코드 유형 일반화 : std::tuple을 사용할 수 있습니다. 튜플을 반복하는 것은 간단하지 않지만이를 수행하는 많은 코드를 찾을 수 있습니다. 최악의 경우 명명 된 변수의 손실이 있습니다.이 변수는 멤버와 비슷합니다.

부스트를 사용하는 경우 Boost.Fusion's 도우미 매크로 BOOST_FUSION_ADAPT_STRUCT을 사용하여 구조체를 퓨전 시퀀스로 전환 한 다음 퓨전 알고리즘과 함께 사용할 수 있습니다.

1

회원 변수가 모두 동일한 유형이 아닌 것으로 가정합니다. 그렇지 않으면 그냥 컨테이너에 던져 넣을 수 있습니다. C++ 11을 사용하는 경우이 문제를 해결할 수있는 방법 중 하나는 tuple입니다. template metaprogramming을 사용하면 튜플의 모든 요소에 대해 루프를 시뮬레이션 할 수 있습니다. 기능 std::tie은이 같은 "반복"할 수있는 귀하의 모든 멤버에 대한 참조와 튜플을 구축 할 것입니다 :

struct DoCorrection 
{ 
    template<typename T> 
    void operator()(T& t) const { /* code goes here */ } 
}; 

for_each(std::tie(x, y, z), DoCorrection()); 
// see linked SO answer for the detailed code to make this special for_each work. 

그런 다음 각 멤버 변수 유형에 대한 operator()을 전문으로 할 수 있습니다. 그러면 수동으로 유형을 추적하지 않고도 자동으로 적절한 수학을 수행 할 수 있습니다.

관련 문제