C ++ 11有没有办法静态测试方法访问级别?

时间:2013-02-18 14:10:13

标签: c++ unit-testing c++11 static-assert

C ++ 11增加了许多新的类模板,允许静态地测试类型特征,即在编译时检测问题。我正在为一个班级编写测试,我需要确保给定的方法是公开的。

“动态”解决方案是创建一个对象并调用该方法,然后编译器会在它不起作用时进行投诉。但是可能会发生不同类型的错误,并且会使得错误消息更加混乱。如果可能,最好使用静态断言测试方法访问级别。

是否有可能或者我真的必须为此创建一个对象?

(另外,如果我需要私有/保护方法,我该怎么办)

2 个答案:

答案 0 :(得分: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, "");
}

答案 1 :(得分:2)

据我所知,以下是standards compliant

#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编译但返回错误的值(在每种情况下都为true!)