2013-03-05 39 views
11

Làm cách nào để phát hiện một hàm thành viên có công cụ sửa đổi const hay không?Tìm hằng số của hàm thành viên

xem xét mã

struct A { 
    int member(); 
    int member() const; 
}; 

typedef int (A::*PtrToMember)(); 
typedef int (A::*PtrToConstMember)() const; 

tôi cần một cái gì đó như thế này:

std::is_const<PtrToMember>::value // evaluating to false 
std::is_const<PtrToConstMember>::value // evaluating to true 
+1

Nếu bạn không biết loại dữ liệu bạn đang xử lý khi bạn viết mã? –

+1

không phải là constness của chức năng thành viên kiểm tra tại thời gian biên dịch? – zzk

+2

@EdHeal Điều gì sẽ xảy ra nếu đó là một đối số mẫu? Sau đó, bạn không biết cho đến khi instantiation. Hãy tưởng tượng rằng bạn muốn sử dụng nó trong một 'enable_if'. – Agentlien

Trả lời

7

Có bạn đi:

#include <type_traits> 
#include <iostream> 
#include <vector> 

template<typename T> 
struct is_const_mem_fn { 
private: 
    template<typename U> 
    struct Tester { 
     static_assert(// will always fail 
      std::is_member_function_pointer<U>::value, 
      "Use member function pointers only!"); 

     // if you want to report false for types other than 
     // member function pointers you can just derive from 
     // std::false_type instead of asserting 
    }; 

    template<typename R, typename U, typename...Args> 
    struct Tester<R (U::*)(Args...)> : std::false_type {}; 

    template<typename R, typename U, typename...Args> 
    struct Tester<R (U::*)(Args...) const> : std::true_type {}; 

public: 
    static const bool value = 
     Tester<typename std::remove_cv<T>::type>::value; 
}; 

struct A { 
    int member(); 
    int member() const; 
}; 
typedef int (A::*PtrToMember)(); 
typedef int (A::*PtrToConstMember)() const; 

int main() 
{ 
    std::cout 
     << is_const_mem_fn<PtrToMember>::value 
     << is_const_mem_fn<const PtrToMember>::value 
     << is_const_mem_fn<PtrToConstMember>::value 
     << is_const_mem_fn<const volatile PtrToConstMember>::value 
     << is_const_mem_fn<decltype(&std::vector<int>::size)>::value; 
} 

Output: 00111

EDIT: Có một trường hợp góc Tôi quên chiếm trong câu trả lời ban đầu.

Các đặc điểm trên sẽ nghẹt thở trên một hàm thành viên giả thuyết như thế này:

struct A { 
    int member(int, ...) const; 
}; 

vì không có chuyên môn hợp lệ Tester có thể được tạo ra cho chữ ký như vậy. Để khắc phục sự cố, hãy thêm các chuyên môn sau:

template<typename R, typename U, typename...Args> 
struct Tester<R (U::*)(Args..., ...)> : std::false_type {}; 

template<typename R, typename U, typename...Args> 
struct Tester<R (U::*)(Args..., ...) const> : std::true_type {}; 
+0

Hoạt động tốt với gcc. Cảm ơn! – Akon

+0

@Akon Bạn được chào đón. Vui lòng kiểm tra câu trả lời cập nhật. – jrok

+0

Cảm ơn bạn một lần nữa vì đã xem xét kỹ câu hỏi của tôi. – Akon

2

Dưới đây là một loại đặc điểm đơn giản chuyển thể từ here rằng nên cho phép điều này.

template <typename T> 
struct is_const_mem_func : std::false_type { }; 

template <typename Ret, typename Class, typename... Args> 
struct is_const_mem_func<Ret (Class::*)(Args...) const> : std::true_type { }; 
+2

Hợp lệ cho 'PtrToMember',' const PtrToMember' và 'PtrToConstMember'. ** NHƯNG ** sai cho 'const PtrToConstMember' – deepmax

+0

Đúng cách. Cảm ơn! – Akon

Các vấn đề liên quan