Lambda-expression作为常量表达式的未求值子表达式

Lambda-expression as an unevaluated sub-expressions of a constant expression

本文关键字:表达式 常量 Lambda-expression      更新时间:2023-10-16

请原谅我的长帖子,但我不能让这个程序工作,除非我指定-fpermissive到gcc,而不是在clang下。你能帮忙修复这个例子吗?

namespace detail
{
template<typename T>
constexpr auto address(T&& t) ->
  typename ::std::remove_reference<T>::type*
{
  return &t;
}
template <typename FP, FP fp, class C, typename ...A>
struct S
{
  static constexpr auto* l = false ? address(
    [](C* const object) noexcept
    {
      return [object](A&& ...args) {
        return (object->*fp)(::std::forward<A>(args)...); 
      };
    }) :
    nullptr
  ;
};
template <typename FP, FP fp, typename R, class C, typename ...A>
auto make_member_delegate(C* const object, R (C::* const)(A...)) ->
  decltype((*S<FP, fp, C, A...>::l)(object))
{
  return (*S<FP, fp, C, A...>::l)(object);
}
}
template <typename FP, FP fp, class C>
auto make_member_delegate(C* const object) ->
  decltype(detail::make_member_delegate<FP, fp>(object, fp))
{
  return detail::make_member_delegate<FP, fp>(object, fp);
}
struct A
{
  void hello()
  {
    ::std::cout << "it worked" << ::std::endl;
  }
};
int main()
{
  A a;
  auto d(make_member_delegate<decltype(&A::hello), &A::hello>(&a));
  d();
  return 0;
}

错误是(首先是gcc,然后是clang++):

gcc-4.9.0:

t.cpp:20:26: error: 'constexpr detail::S<void (A::*)(), &A::hello, A>::<lambda(A*)>* const detail::S<void (A::*)(), &A::hello, A>::l', declared using local type 'detail::S<void (A::*)(), &A::hello, A>::<lambda(A*)>', is used but never defined [-fpermissive]
   static constexpr auto* l = false ? address(

叮当声+ + 3.4.2:

t.cpp:21:5: error: a lambda expression may not appear inside of a constant expression
    [](C* const object) noexcept
    ^
t.cpp:33:14: note: in instantiation of template class 'detail::S<void (A::*)(), &A::hello, A>' requested here
  decltype((*S<FP, fp, C, A...>::l)(object))
             ^
t.cpp:32:6: note: while substituting deduced template arguments into function template 'make_member_delegate' [with FP = void
      (A::*)(), fp = &A::hello, R = void, C = A, A = <>]
auto make_member_delegate(C* const object, R (C::* const)(A...)) ->
     ^
t.cpp:41:6: note: while substituting deduced template arguments into function template 'make_member_delegate' [with FP = void
      (A::*)(), fp = &A::hello, C = A]
auto make_member_delegate(C* const object) ->

奇怪的是,规范的python示例在clang-3.4.2

下编译时没有问题

这是gcc-4.9.0的修复,但程序仍然无法与clang-3.4.2编译:

template <typename FP, FP fp, typename R, class C, typename ...A>
auto make_delegate(C* const object, R (C::* const)(A...)) ->
  decltype((*decltype(S<FP, fp, C, A...>::l)(nullptr))(object))
{
  return (*decltype(S<FP, fp, C, A...>::l)(nullptr))(object);
}