2017-05-23 4 views
2

私はテンプレートで遊んできましたが、関数に与えられたテンプレートタイプに特定の静的メンバーがあることを強制したいと思います。残念ながら、タイプ形質はstd::is_staticではありません。メンバー変数がC++ 17で 'static'とマークされているというstatic_assertですか?

私はそれを使用する方法のラフな例(または代替):

template<typename T> 
void SomeFunc(T& obj) 
{ 
    static_assert(std::is_static_v<decltype(T::someVariable)>, "someVariable must be static"); 
} 

は、行動のこの種を達成するための任意の方法はありますか?私はちょうど

template<typename T> 
void SomeFunc(T& obj) 
{ 
    // must be static 
    T::someVariable; 
} 

を書くことができしかし、これはまともなメッセージとstatic_assertほど素敵または有益近くのどこかではないでしょう。これは一種のちょうど構文エラーです:(私はあなたが望むものを正しく理解していれば

ありがとう!

+0

もちろん、ここで得られる最も良いのは構文エラーです。コンパイラは 'T :: someVariable'を解決しようとしています。それができない場合、もちろんそれはコンパイラのエラーです。これを回避する方法はありません。 'T :: someVariable'が静的なメンバか関数かをチェックしたいなら、' type_traits'ヘッダを使います。 – nakiya

+0

それは私の指摘でした - 私は問題を解決するためにtype_traitsを使用する方法を理解できませんでした:)しかし、max66の答えはそれをカバーするようです。 – HateDread

+0

@HateDread - 納屋の異論は確かではありませんが、私は自分の答えを改善しました。 – max66

答えて

4

、あなたはstd::is_member_pointerを探している(またはstd::is_member_pointerの値の反対)している。

アン例(また、C++ 11とC++ 14準拠)

#include <type_traits> 

struct foo 
{ int value; }; 

struct bar 
{ static int value; }; 

int main() 
{ 
    static_assert(
     true == std::is_member_pointer<decltype(&foo::value)>::value, "!"); 
    static_assert(
     false == std::is_member_pointer<decltype(&bar::value)>::value, "!!"); 
} 

- EDIT -

次の例では、私はsomeValuestaticない場合は、テンプレート引数が(someValue静的メンバとfalse otherwhiseを持っている場合truevalueを設定するタイプの特性(hasSomeValueStatic)を開発しましたnakiyaの異議を理解してくださいますが...ありませんのうちにはsomeValueがありません。

#include <iostream> 
#include <type_traits> 

struct foo 
{ int someValue; }; 

struct bar 
{ static int someValue; }; 

template <typename, typename = int> 
struct hasSomeValueStatic : std::false_type 
{ }; 

template <typename T> 
struct hasSomeValueStatic<T, decltype(T::someValue, 0)> 
     : std::integral_constant<bool, 
      ! std::is_member_pointer<decltype(&T::someValue)>::value> 
{ }; 

int main() 
{ 
    std::cout << hasSomeValueStatic<foo>::value << std::endl; // print 0 
    std::cout << hasSomeValueStatic<bar>::value << std::endl; // print 1 
    std::cout << hasSomeValueStatic<int>::value << std::endl; // print 0 
} 
+0

He/sheは、存在しない 'T :: someVariable'にアクセスしようとすると、コンパイラエラーの代わりに"エラーメッセージ "を取得します。 – nakiya

+0

@nakiya - あなたの異議を理解していないのですが...答えが変更されました。 – max66

+0

ありがとうございましたmax66、これは私が後にしたものです!私はそれが存在するかどうか心配していません。なぜなら、以前のチェックがあるからです(この特定の問題には関係していないと考えていたので言及しません)。私が心配しなければならない 'std :: is_member_pointer'の制限や不具合はありますか? – HateDread

関連する問題