2009-12-16 3 views
5

other my question 기준.회원 특성이나 이에 대한 포인터가 있습니까?

내가 템플릿 매개 변수로 value_typesize을 사용할 수 있습니다, 다음 코드를

template<typename T, int N> 
struct A { 
    typedef T value_type; // save T to value_type 
    static const int size = N; // save N to size 
}; 

봐를 생각해 보자.

struct Foo { 
    int m; 
    int r; 
}; 

template<int Foo::*Mem> 
struct B { 
    static int Foo::* const mp; 
}; 

template<int Foo::*Mem> 
int Foo::* const B<Mem>::mp = Mem; // Save pointer to member 

하지만 오류가 발생합니다 :

typedef A<int, 2> A1; 
typedef A<A1::value_type, A1::size + 3> A2; // OK, A2 is A<int,5> 

는 지금은 멤버 포인터와 동일한 작업을 수행합니다.

typedef B<&Foo::m> B1; 
typedef B<B1::mp> B2; // DOES NOT WORK 

마지막 줄을 작동시키는 방법은 무엇입니까? 또는 similiary 결과를 얻는 방법?

참고. 그것이 작동하지 않는다는 것을 알고 있습니다. C++ 표준에 대한 링크가 필요하지 않습니다. 해결 방법이 필요합니다.

+1

오류 무엇입니까? 나는 그것이 잘 작동 할 것이라고 확신하며, GCC 4.1.2에서 작동한다. –

+0

VS2008 컴파일러를 사용합니다. –

+0

멤버 클래스 타입에 대한 템플릿 매개 변수에 전달할 수있는 합법적 인 값은'& ClassName :: MemberName'이거나 0입니다 - C++ 03 14.3.2 및 14.3.2를 참조하십시오. 5.3.1. 무엇보다도, 위의 코드에서,'B1 :: mp'는 컴파일 타임 상수 표현이 아닙니다. –

답변

0

마이크가 올바르게 컴파일되어야합니다. VS에서 bug입니다.

+0

ha-ha! 이건 내 벌레 야. 나는이 버그를 게시했다. 그러나 이것은 사실이 아닙니다. typedef가 구조체에 없습니다. –

+0

Comeau도 오류 보내주세요. –

1

은 C++ 표준 5.19/2에 따라 작동하지 않아야

다른 표현은 일정한 표현을 고려 만 비 지역 정적 객체 초기화 (3.6.2)의 용도. 어드레스 상수 식 - 널 포인터 값 (4.10),
- - 널 부재 포인터 값 (4.11),
- 연산 상수 식

: 이러한 일정한 표현은 다음 중 하나를 평가한다
- 기준 상수 식
- 전체 오브젝트 유형에 대한 어드레스 정수 표현을 더하거나 뺀 정수 상수 식
또는
- 부재 상수 식 포인터.

원래의 질문에 대한 대답이 아니지만, this에 대한 대답은 잘못된 것입니다.

0

전적으로 대답은 아니지만 Mem에 직접 액세스 할 수 있습니까?

즉 : B1 :: Mem 대신 B1 :: Mem.

우리가 일반적으로 typedef 템플릿 이름을 사용하기 때문에 표준을 허용하지 않는다는 것을 확신하지만 실제로는 직접 액세스하지 않고 유형을 지정할 때 기술적으로 허용 할 수 있습니다 (함축적 인 것이 확실하지 않음). 런타임시에 수행되는 정적 멤버의 초기화가 필요하기 때문에 솔루션이 작동하지 않을 수도 있습니다 (잘못된 부분은 수정하십시오). 그래서 원하는대로 컴파일 타임에 액세스 할 수 없습니다.

아마 당신은 우리에게 당신이 적절한 해결이 가능 있는지 확인하기 위해 당신의 특성/정책 클래스 뭘 하려는지의 큰 그림을 제공 시도 할 수 있습니다.

0

그런 것이 없다고 생각해서 놀랐습니다. 예를 들어, 예상되는 장소에서 적어도 :

여기 아무것도 http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/index.html 도 여기 근처 http://en.cppreference.com/w/cpp/types/is_member_pointer

http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html을 기반으로하고 자신의 롤하기 어려운되지 않습니다 http://en.cppreference.com/w/cpp/types/is_member_pointer 없습니다.

#include<type_traits> // std::is_pointer_member 

template<class MP> struct member_pointer_traits_helper; 

template< class T, class U > 
struct member_pointer_traits_helper<T U::*>{ 
    using class_type = U; 
    using declaration_type = T; 
}; 

template< class MP > 
struct member_pointer_traits : 
member_pointer_traits_helper<typename std::remove_cv<MP>::type> {}; 

struct B{ 
    int b; 
}; 

int main(){ 
    using std::same; 

    static_assert(std::is_member_pointer<int B::*>::value == true, ""); 
    static_assert(is_same<member_pointer_traits<int B::*>::class_type, B>{}, ""); 
    static_assert(is_same<member_pointer_traits<int B::*>::declaration_type, int>{}, ""); 
    static_assert(is_same<member_pointer_traits<decltype(&B::b)>::declaration_type, int>{}, ""); 
// static_assert(is_same<member_pointer_traits<double>::class_type, B>{}, ""); // error 
} 

이름이 적합한 지 확실하지 않습니다. 또한 비 멤버 포인터에 적용하면 컴파일러 오류가 발생합니다 (이 디자인은 http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html에서 복사 됨) void은 클래스 또는 멤버 유형이 아니기 때문에 분명히 오류가 반환되는 void 유형을 반환 할 수 있습니다.)

(약간의 수정을하면 C++ 98에서 사용할 수 있으며 C++ 11을 사용하면 더 명확하게 나타납니다.)