0

C++11 では、型特性を静的にテストできる、つまりコンパイル時に問題を検出できる、新しいクラス テンプレートが多数追加されています。クラスのテストを書いていますが、特定のメソッドが公開されていることを確認する必要があります。

「動的な」解決策は、オブジェクトを作成してメソッドを呼び出すことです。それが機能しない場合、コンパイラは文句を言います。ただし、別の種類のエラーが発生する可能性があり、結果として生じるエラー メッセージがよりわかりにくくなります。可能であれば、静的アサーションを使用してメソッド アクセス レベルをテストすることをお勧めします。

それは可能ですか、それとも本当にそのためのオブジェクトを作成する必要がありますか?

(また、メソッドを非公開/保護する必要がある場合はどうすればよいですか)

4

2 に答える 2

2

私が知る限り、以下は標準に準拠しています

#include <type_traits>

template<typename T,typename=void>
struct NullaryFooCanBeCalled:std::false_type {};

template<typename T>
struct NullaryFooCanBeCalled<
      T,
      typename std::enable_if<
         std::is_same<
               decltype(std::declval<T>().Foo()),
               decltype(std::declval<T>().Foo())
         >::value >::type
      >:
   std::true_type {};



struct PrivateFoo {private:void Foo() {}};
struct PublicFoo {public:void Foo() {}};
struct ProtectedFoo {protected:void Foo() {}};
struct StrangeFoo {
   struct Bar { void operator()() {}; };
   Bar Foo;
};

#include <iostream>

int main() {
   std::cout << "PrivateFoo:" << NullaryFooCanBeCalled<PrivateFoo>::value << "\n";
   std::cout << "PublicFoo:" << NullaryFooCanBeCalled<PublicFoo>::value << "\n";
   std::cout << "ProtectedFoo:" << NullaryFooCanBeCalled<ProtectedFoo>::value << "\n";
   std::cout << "StrangeFoo:" << NullaryFooCanBeCalled<StrangeFoo>::value << "\n";
}

一方、コンパイラのサポートは、この言語の癖に対して貧弱です。

Clang 3.2はコンパイルして動作します。 gcc 4.7.2がビルドに失敗します。 Intel 13.0.1はコンパイルしますが、間違った値を返します (すべての場合に当てはまります!)

于 2013-02-18T16:06:54.490 に答える
2

これは私のためにコンパイルされます:

#include <type_traits>

namespace has_foo_imp
{

template <class T>
auto
test(T&& t) -> decltype(t.foo(), std::true_type());

auto
test(...) -> std::false_type;

}  // has_foo_imp

template <class T>
struct has_foo
    : public std::integral_constant<bool,
                        decltype(has_foo_imp::test(std::declval<T>()))::value>
{
};

class A
{
    void foo();
public:
};

class B
{
public:
    void foo();
};

int
main()
{
    static_assert(!has_foo<A>::value, "");
    static_assert( has_foo<B>::value, "");
}
于 2013-02-18T15:31:31.437 に答える