2014-03-27 3 views
3

헤더 전용으로 유지하려는 라이브러리를 작성 중입니다. 나는 이름이 "quux :: foo는"함께 호출 법인이 두 가지 방법을 참조기능 개체 대 머리글 전용 라이브러리의 기능

// Wrapper.h 
#ifndef INCLUDED_WRAPPER_H 
#define INCLUDED_WRAPPER_H 

namespace quux { 

template <typename T, typename U> 
class Wrapper 
{ 
    T m_t; 
    U m_u; 
public: 
    Wrapper(T const & t, U const & u) : m_t(t), m_u(u) { } 

    // ... 
}; 

} // namespace quux 

#endif // INCLUDED_WRAPPER_H 

// Foo.h 
#ifndef INCLUDED_FOO_H 
#define INCLUDED_FOO_H 

#include <type_traits> 

#include "Wrapper.h" 

namespace quux { 

// if some type is special, then there will be a specialization of this 
// struct derived from std::true_type 
template <typename T> struct is_special : std::false_type { }; 

class Foo 
{ 
    template <typename T> 
    Wrapper<Foo, T> impl(T const & t, std::true_type) const 
    { 
    return Wrapper<Foo, T>(*this, t); 
    } 

    template <typename T> 
    T const & impl(T const & t, std::false_type) const; 
    { 
    return t; 
    } 
public: 

    template <typename T> 
    auto operator()(T const & t) const // using automatic return type deduction 
    { 
    return impl(t, is_special<T>()); 
    } 

}; 

#if 1 
Foo const foo; 
#else 
template <typename T> 
auto foo(T const & t) // using automatic return type deduction 
{ 
    return Foo()(t); 
} 
#endif 

} // namespace quux 

#endif // INCLUDED_FOO_H 

: (- 지점의 #if 1) 또는 일정한 객체 foo라는 코드에서이 같은 뭔가를 인수를 Foo 객체 (# else-branch)로 전달하는 foo라는 함수. 어느 버전을 선호합니까? const 개체는 내부 링크가 있으므로 헤더가 여러 번역 단위에 포함되어 있으면 링커 오류가 발생하지 않습니다. 두 가지 접근법간에 현저한 차이가 있습니까?

답변

0

함수를 호출하고 함수 객체에 상태가 없으므로 함수 인터페이스를 사용할 것입니다.

먼저 함수가 오버로드 될 수 있기 때문에 함수 개체는 함수 개체의 본문 외부에있을 수 없기 때문에. 함수에 ADL 확장을 사용 가능하게 할 수 있습니다.

둘째, 기능 개체가 이상하기 때문입니다. 예를 들어 함수 포인터로 변환 할 수는 없습니다. (더 많은 상용구로 해결할 수 있습니다.) 이상한 솔루션은 단순한 솔루션이 충분하지 않은 경우에만 좋은 아이디어입니다.이 경우 간단한 완벽한 전달 기능이 더 간단합니다.

마지막으로 함수를 앞으로 완벽하게 만들고 T&&의 평점에 T을 최 외곽 API 수준으로 반환하는 함수를 제공 할 수 있습니다. 이로써 임시 직원의 평생 확장이 기능을 통과 할 수 있습니다.