0

I tried to use the following code to test whether calling a member function on a pointer to class using operator ->* is noexcept

// test.cc
#include <type_traits>
template <class T> auto declval() noexcept -> std::add_rvalue_reference_t<T>;
template <class T, class P, class ...Args> constexpr const static inline bool __is_nothrow_pointer_to_function_member_accessable_v = noexcept( (declval<T>()->*declval<P>())(declval<Args>()...) );

struct A {
    int i;
    int F() { return 0; }
    int F(int) noexcept { return 0; }
    int F(bool) & noexcept { return 0; }
    int F(bool) && { return 1; }
};

int main() {
 static_assert(__is_nothrow_pointer_to_function_member_accessable_v<A*, int (A::*)(int), int>);
    static_assert(__is_nothrow_pointer_to_function_member_accessable_v<A*, int (A::*)(bool) &, bool>);
}

I compiled it using command clang++-5.0 -std=c++17 test.cc and the 2 static asserts failed.

JiaHao Xu
  • 2,452
  • 16
  • 31
  • Obviously, you can't test anything without specifying what you are testing. *Set of potential exceptions* for a function pointer (or a member function pointer) is "infinite" (i.e. *all types*), unless you explicitly make this function pointer "noexcept". In your case your pointers are not marked noexcept, which means that their *set of potential exceptions* is "infinite" and assertion fails. – AnT stands with Russia Jul 12 '18 at 15:44
  • This doesn't address the question, but names that contain two consecutive underscores (`__is_nothrow_pointer_to_function_member_accessable_v`) and names that begin with an underscore followed by a capital letter are reserved for use by the implementation. Don't use them in your code. – Pete Becker Jul 12 '18 at 17:33
  • @AnT It works, thanks. Can u make that an answer? – JiaHao Xu Jul 13 '18 at 01:15

0 Answers0