2013-03-05 13 views
11

メンバ関数がconst修飾子を持つかどうかを検出する方法はありますか?以下はメンバ関数の定数の検索

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

コードの作成時に扱っているデータ型を知りませんか? –

+1

は、コンパイル時にチェックされるメンバ関数の定数ではありませんか? – zzk

+2

@EdHealテンプレート引数の場合はどうなりますか?次にインスタンス化まではわかりません。あなたが 'enable_if'でそれを使いたいとします。 – Agentlien

答えて

7

あなたが行く:

#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; 
} 

出力:00111

EDIT:私は、元の答えに説明するために忘れてしまったコーナーケースがあります。このような署名を生成することができるTesterの有効な特殊化がないため

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

:上記

形質は、このような仮定のメンバ関数にチョークであろう。それを修正するには、次のスペシャライゼーションを追加してください。

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

gccでうまく動作します。ありがとう! – Akon

+0

@Akonようこそ。更新された回答も確認してください。 – jrok

+0

もう一度深くおねがいします。 – Akon

2

これを許可する必要がありhereから適応単純型形質である:。

は、私がこのような何かを必要とするコード

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

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

を考えてみましょうそこ

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

'PtrToMember'、' const PtrToMember'、 'PtrToConstMember'に対して有効です。 ** BUT **は 'const PtrToConstMember'のために間違っています – deepmax

+0

正しい方法です。ありがとう! – Akon

関連する問題