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 {};
Nếu bạn không biết loại dữ liệu bạn đang xử lý khi bạn viết mã? –
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
@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