2013-08-27 2 views
1

C++에서 값 비싼 2D 함수를 자동으로 보간하는 메서드를 작성했습니다. 나는 지금 어떤 함수가 보간 될 수 있도록 함수 포인터를 받아들이도록 클래스를 허용하려하고있다. 이렇게하려면 함수 포인터를 평가하는 데 필요한 각 개체에 템플릿을 적용 할 수 있도록 템플릿 기반 클래스가 필요합니다. 링커가 필요한 각 객체에 대해 클래스를 템플릿화할 수 있도록 클래스에서 전적으로 클래스를 정의해야한다는 것을 깨닫고 나중에 그렇게 나쁘지는 않습니다. 이제 문질러.템플릿 클래스 내에서 boost :: unordered_map의 boost :: tuple 문제가 발생했습니다.

클래스 내에서 불필요하게 함수를 호출하지 않도록 boost :: unordered_map을 사용하여 함수 평가를 저장합니다. 보간하는 동안 그리드를 수정하여 (곡률에 따라) 충분히 묘사합니다. 나는 원래의 점이 x = 0, .5, 1 일 때 다음 집합이 x = 0, .25, .5, 1이 될 수 있도록 메쉬를 로컬에서 세분화했다. 두 번째 패스는 x = .25입니다. 동적 함수 포인터 대신 하드 코딩 된 함수로 자체 작업하고 있습니다.

문제는 boost :: tuple에 필요한 연산자와 hash_value 함수를 정의하는 데 있습니다. 헤더에 넣으면 헤더의 각 포함에 대해 여러 번 정의됩니다. 내가 그것을 객체로 컴파일하고 링크한다면, 링커는 정의를 찾지 못한다. ommitions와 내 템플릿 클래스 이상

struct BoostTuple2D { 
    BoostTuple2D(double x1, double x2) 
     : tuple(x1, x2) {} 
    boost::tuples::tuple<double, double> tuple; 
}; 

typedef boost::unordered_map< BoostTuple2D, double > BoostTuple2DMap; 

, :

template<class F> 
class Interpolate { 
public: 
    class Evaluate { 
    // this class uses the map to cache evaluations of the dynamic pointer 
     } 

    Interpolate (double (F::*f)(double, double), F & obj, [...]) : f(f), object(obj), ... {}; 

private: 
    // members 
}; 
내가 구조체 및 타입 정의가

bool operator==(const BoostTuple2D &a, const BoostTuple2D &b) 
{ 
    return a.tuple.get<0>() == b.tuple.get<0>() && 
      a.tuple.get<1>() == b.tuple.get<1>(); 
} 

std::size_t hash_value(const BoostTuple2D &e) 
{ 
    std::size_t seed = 0; 
    boost::hash_combine(seed, e.tuple.get<0>()); 
    boost::hash_combine(seed, e.tuple.get<1>()); 
    return seed; 
} 

을 내 헤더 : 두 정의는 I 클래스에서 참조해야

연산자를 == 및 hash_value 메서드를 여러 번 정의하지 않고 클래스에서 사용할 수있게하려면 어떻게해야합니까? 헤더 파일을 지키고 있습니다. 나는 C++ newbee 다. 그래서 희망을 갖고 그 단순한 무엇인가 얻지 않고있다. 감사!

답변

1

헤더에 템플릿이 아닌 방법의 경우 '인라인'키워드를 먼저 사용해야합니다. 함수가 인라인 될 것이라는 보장은 없지만 (이 경우 힌트 일뿐) 링커에서 여러 정의를 허용해야합니다. 당신은 문제가 자신의 소스 파일에 배치하지만, hedaer에 선언을 떠날가 발생하는 경우

inline bool operator==(const BoostTuple2D &a, const BoostTuple2D &b) 
{ 
    return a.tuple.get<0>() == b.tuple.get<0>() && 
      a.tuple.get<1>() == b.tuple.get<1>(); 
} 

std::size_t hash_value(const BoostTuple2D &e) 
{ 
    std::size_t seed = 0; 
    boost::hash_combine(seed, e.tuple.get<0>()); 
    boost::hash_combine(seed, e.tuple.get<1>()); 
    return seed; 
} 

것은, 당신이 그들을 가하고있는 네임 스페이스에 문제가있을 수 있습니다. 내가 볼해야 도움이되는 코드의 버전.

참고로 튜플에는 이미 operator==이 정의되어 있어야합니다. 따라서 요소별로 직접 요소를 비교하는 대신 사용할 수 있습니다 (기본값은 이미 그렇게하고 있습니다).

+0

감사합니다. 실제로이 작업은 컴파일되고 작동합니다 (인라인). 나는 인라인 주위에 떨어져 있다고 가정하지 않습니까? – ccook

+0

@ccook : 선언문을 헤더에 넣은 다음 소스 파일을 정의합니다. 당신은 당신의 포스트에서 당신이 그것을 시도했을 때 작동하지 않는다는 문제점이 있다고 말했지만 가능해야합니다. –

관련 문제