Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
312 views
in Technique[技术] by (71.8m points)

c++ - Can I use the result of a C++17 captureless lambda constexpr conversion operator as a function pointer template non-type argument?

While answering How do I write a lambda expression that looks like a method?, I tried to turn a captureless lambda into a member function pointer by exploiting the fact that, since C++17, captureless lambdas have a constexpr conversion operator to their function pointer type.

So I came up with an issue boiling down to:

template<void(*)()> struct A{};

int main()
{
  A<static_cast<void(*)()>([]{})>{}; // 1

  constexpr auto fp = static_cast<void(*)()>([]{});
  A<fp>{}; // 2
}

Now, this compiles in clang (since 5.0.0) but gcc(>=7.2) complains:

error: lambda-expression in template-argument
   A<static_cast<void(*)()>([]{ /*whatever*/ })>{}; // 1
                            ^
error: 'main()::<lambda()>::_FUN' is not a valid template argument for type 'void (*)()' because 'static constexpr void main()::<lambda()>::_FUN()' has no linkage
   A<fp>{}; // 2

The question is, who's right?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is a gcc bug, filed 83258.

In C++14, we used to have a linkage requirement for non-type template parameters of pointer type. But in C++17 (as a result of N4268), the parameter just needs to be a converted constant expression of the correct type, with a few other restrictions (none of which are relevant here). Once we can construct fp, we should be able to use it as a template parameter.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...