Skip to content

Fix compilation errors for C++20#1329

Closed
stac47 wants to merge 1 commit into
facebook:masterfrom
stac47:fix_for_cxx20
Closed

Fix compilation errors for C++20#1329
stac47 wants to merge 1 commit into
facebook:masterfrom
stac47:fix_for_cxx20

Conversation

@stac47

@stac47 stac47 commented Mar 6, 2020

Copy link
Copy Markdown
Contributor

Compiling with gcc 10.0.1 and -std=gnu++2a, we have the following errors:

/home/docker/opensource/folly/folly/FBString.h:1013:33: error: no type named 'reference' in 'class std::allocator<char>'
 1013 |   typedef typename A::reference reference;
      |                                 ^~~~~~~~~
/home/docker/opensource/folly/folly/FBString.h:1014:39: error: no type named 'const_reference' in 'class std::allocator<char>'
 1014 |   typedef typename A::const_reference const_reference;

This is due to the fact many members in std::allocator have been remove in C++20: https://en.cppreference.com/w/cpp/memory/allocator

We also have this one due to the new way C++ resolves the comparison operators:

/home/docker/opensource/folly/folly/dynamic-inl.h:854:20: error: ambiguous overload for 'operator!=' (operand types are 'folly::dynamic::const_item_iterator' and 'folly::dynamic::const_item_iterator')
  854 |   return find(key) != items().end() ? 1u : 0u;
      |          ~~~~~~~~~ ^~ ~~~~~~~~~~~~~
      |              |                   |
      |              |                   folly::dynamic::const_item_iterator
      |              folly::dynamic::const_item_iterator
In file included from /home/docker/opensource/folly/folly/dynamic-inl.h:25,
                 from /home/docker/opensource/folly/folly/dynamic.h:796,
                 from /home/docker/opensource/folly/folly/dynamic.cpp:17:
/home/docker/opensource/folly/folly/detail/Iterators.h:80:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator==(const D&) const [with D = folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::f
orward_iterator_tag]' (reversed)
   80 |   bool operator==(D const& rhs) const {
      |        ^~~~~~~~
/home/docker/opensource/folly/folly/detail/Iterators.h:98:3: note: candidate: 'typename std::enable_if<std::is_convertible<D, D2>::value, bool>::type folly::detail::IteratorFacade<D, V, Tag>::operator==(const D2&) const [with D2 = folly::dynamic::const_item_iterator; D =
 folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::forward_iterator_tag; typename std::enable_if<std::is_convertible<D, D2>::value, bool>::type = bool]' (reversed)
   98 |   operator==(D2 const& rhs) const {
      |   ^~~~~~~~
/home/docker/opensource/folly/folly/detail/Iterators.h:84:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator!=(const D&) const [with D = folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::f
orward_iterator_tag]'
   84 |   bool operator!=(D const& rhs) const {
      |        ^~~~~~~~
/home/docker/opensource/folly/folly/detail/Iterators.h:103:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator!=(const D2&) const [with D2 = folly::dynamic::const_item_iterator; D = folly::dynamic::const_item_iterator; V = const std::pair<const f
olly::dynamic, folly::dynamic>; Tag = std::forward_iterator_tag]'
  103 |   bool operator!=(D2 const& rhs) const {
      |        ^~~~~~~~

@yfeldblum yfeldblum left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of comments but otherwise looks good to me.

Comment thread folly/FBString.h Outdated
Comment on lines 1010 to 1011
typedef typename A::size_type size_type;
typedef typename A::difference_type difference_type;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://en.cppreference.com/w/cpp/named_req/Allocator

size_type and difference_type are also optional - should these also be using std::allocator_traits?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use std::allocator_traits but as these members are still in std::allocator and are not flagged as deprecated, I think it is not mandatory. Up to you.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But they may not exist in other allocator types besides std::allocator.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True.

Comment thread folly/detail/Iterators.h Outdated
Comment on lines +97 to +98
typename std::enable_if_t<!std::is_same<D, D2>::value, int> = 0,
typename std::enable_if_t<std::is_convertible<D, D2>::value, int> = 0>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two typenames don't seem necessary.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think they are in C++ 20. Let's take an example:

  854 |   return find(key) != items().end() ? 1u : 0u;                                                                                                                                                                                                                               |          ~~~~~~~~~ ^~ ~~~~~~~~~~~~~
      |              |                   |
      |              |                   folly::dynamic::const_item_iterator
      |              folly::dynamic::const_item_iterator

In C++20, evaluating operator!= will lead to add operator!=, operator== and reversed operator== in the candidates list. If you don't desambiguate operator== when the type is the same you will have twice the same primary operator.

This said, these two lines simply implement the comment just above:

   * Does a conversion of D (or D reference) to D2, if one exists (otherwise
   * this is disabled).  Disabled if D and D2 are the same, to disambiguate
   * this and the `operator==(D const&) const` method above.

Regards,
Laurent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overload control looks necessary but the use of the keyword typename seems superfluous.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. PR updated.

@facebook-github-bot facebook-github-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yfeldblum has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot

Copy link
Copy Markdown
Contributor

@yfeldblum merged this pull request in dacd7bf.

facebook-github-bot pushed a commit that referenced this pull request Mar 25, 2020
Summary:
Compiling with gcc 10.0.1 and -std=gnu++2a, we have the following errors:
```
folly/FBString.h:1013:33: error: no type named 'reference' in 'class std::allocator<char>'
 1013 |   typedef typename A::reference reference;
      |                                 ^~~~~~~~~
folly/FBString.h:1014:39: error: no type named 'const_reference' in 'class std::allocator<char>'
 1014 |   typedef typename A::const_reference const_reference;
```
This is due to the fact many members in `std::allocator` have been remove in C++20: https://en.cppreference.com/w/cpp/memory/allocator

We also have this one due to the new way C++ resolves the comparison operators:
```
folly/dynamic-inl.h:854:20: error: ambiguous overload for 'operator!=' (operand types are 'folly::dynamic::const_item_iterator' and 'folly::dynamic::const_item_iterator')
  854 |   return find(key) != items().end() ? 1u : 0u;
      |          ~~~~~~~~~ ^~ ~~~~~~~~~~~~~
      |              |                   |
      |              |                   folly::dynamic::const_item_iterator
      |              folly::dynamic::const_item_iterator
In file included from folly/dynamic-inl.h:25,
                 from folly/dynamic.h:796,
                 from folly/dynamic.cpp:17:
folly/detail/Iterators.h:80:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator==(const D&) const [with D = folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::f
orward_iterator_tag]' (reversed)
   80 |   bool operator==(D const& rhs) const {
      |        ^~~~~~~~
folly/detail/Iterators.h:98:3: note: candidate: 'typename std::enable_if<std::is_convertible<D, D2>::value, bool>::type folly::detail::IteratorFacade<D, V, Tag>::operator==(const D2&) const [with D2 = folly::dynamic::const_item_iterator; D =
 folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::forward_iterator_tag; typename std::enable_if<std::is_convertible<D, D2>::value, bool>::type = bool]' (reversed)
   98 |   operator==(D2 const& rhs) const {
      |   ^~~~~~~~
folly/detail/Iterators.h:84:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator!=(const D&) const [with D = folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::f
orward_iterator_tag]'
   84 |   bool operator!=(D const& rhs) const {
      |        ^~~~~~~~
folly/detail/Iterators.h:103:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator!=(const D2&) const [with D2 = folly::dynamic::const_item_iterator; D = folly::dynamic::const_item_iterator; V = const std::pair<const f
olly::dynamic, folly::dynamic>; Tag = std::forward_iterator_tag]'
  103 |   bool operator!=(D2 const& rhs) const {
      |        ^~~~~~~~
```
Pull Request resolved: #1329

Reviewed By: markisaa

Differential Revision: D20458078

Pulled By: yfeldblum

fbshipit-source-id: 15a6a4cfa0f71d45046ee2a13914672b3746b9eb
dotconnor pushed a commit to 5448C8/folly that referenced this pull request Mar 19, 2021
Summary:
Compiling with gcc 10.0.1 and -std=gnu++2a, we have the following errors:
```
folly/FBString.h:1013:33: error: no type named 'reference' in 'class std::allocator<char>'
 1013 |   typedef typename A::reference reference;
      |                                 ^~~~~~~~~
folly/FBString.h:1014:39: error: no type named 'const_reference' in 'class std::allocator<char>'
 1014 |   typedef typename A::const_reference const_reference;
```
This is due to the fact many members in `std::allocator` have been remove in C++20: https://en.cppreference.com/w/cpp/memory/allocator

We also have this one due to the new way C++ resolves the comparison operators:
```
folly/dynamic-inl.h:854:20: error: ambiguous overload for 'operator!=' (operand types are 'folly::dynamic::const_item_iterator' and 'folly::dynamic::const_item_iterator')
  854 |   return find(key) != items().end() ? 1u : 0u;
      |          ~~~~~~~~~ ^~ ~~~~~~~~~~~~~
      |              |                   |
      |              |                   folly::dynamic::const_item_iterator
      |              folly::dynamic::const_item_iterator
In file included from folly/dynamic-inl.h:25,
                 from folly/dynamic.h:796,
                 from folly/dynamic.cpp:17:
folly/detail/Iterators.h:80:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator==(const D&) const [with D = folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::f
orward_iterator_tag]' (reversed)
   80 |   bool operator==(D const& rhs) const {
      |        ^~~~~~~~
folly/detail/Iterators.h:98:3: note: candidate: 'typename std::enable_if<std::is_convertible<D, D2>::value, bool>::type folly::detail::IteratorFacade<D, V, Tag>::operator==(const D2&) const [with D2 = folly::dynamic::const_item_iterator; D =
 folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::forward_iterator_tag; typename std::enable_if<std::is_convertible<D, D2>::value, bool>::type = bool]' (reversed)
   98 |   operator==(D2 const& rhs) const {
      |   ^~~~~~~~
folly/detail/Iterators.h:84:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator!=(const D&) const [with D = folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::f
orward_iterator_tag]'
   84 |   bool operator!=(D const& rhs) const {
      |        ^~~~~~~~
folly/detail/Iterators.h:103:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator!=(const D2&) const [with D2 = folly::dynamic::const_item_iterator; D = folly::dynamic::const_item_iterator; V = const std::pair<const f
olly::dynamic, folly::dynamic>; Tag = std::forward_iterator_tag]'
  103 |   bool operator!=(D2 const& rhs) const {
      |        ^~~~~~~~
```
Pull Request resolved: facebook#1329

Reviewed By: ot, igorsugak

Differential Revision: D20443631

Pulled By: yfeldblum

fbshipit-source-id: 03e8210a64a3eeaefb6f14afaddf45be882e3ba6
dotconnor pushed a commit to 5448C8/folly that referenced this pull request Mar 19, 2021
Summary:
Compiling with gcc 10.0.1 and -std=gnu++2a, we have the following errors:
```
folly/FBString.h:1013:33: error: no type named 'reference' in 'class std::allocator<char>'
 1013 |   typedef typename A::reference reference;
      |                                 ^~~~~~~~~
folly/FBString.h:1014:39: error: no type named 'const_reference' in 'class std::allocator<char>'
 1014 |   typedef typename A::const_reference const_reference;
```
This is due to the fact many members in `std::allocator` have been remove in C++20: https://en.cppreference.com/w/cpp/memory/allocator

We also have this one due to the new way C++ resolves the comparison operators:
```
folly/dynamic-inl.h:854:20: error: ambiguous overload for 'operator!=' (operand types are 'folly::dynamic::const_item_iterator' and 'folly::dynamic::const_item_iterator')
  854 |   return find(key) != items().end() ? 1u : 0u;
      |          ~~~~~~~~~ ^~ ~~~~~~~~~~~~~
      |              |                   |
      |              |                   folly::dynamic::const_item_iterator
      |              folly::dynamic::const_item_iterator
In file included from folly/dynamic-inl.h:25,
                 from folly/dynamic.h:796,
                 from folly/dynamic.cpp:17:
folly/detail/Iterators.h:80:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator==(const D&) const [with D = folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::f
orward_iterator_tag]' (reversed)
   80 |   bool operator==(D const& rhs) const {
      |        ^~~~~~~~
folly/detail/Iterators.h:98:3: note: candidate: 'typename std::enable_if<std::is_convertible<D, D2>::value, bool>::type folly::detail::IteratorFacade<D, V, Tag>::operator==(const D2&) const [with D2 = folly::dynamic::const_item_iterator; D =
 folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::forward_iterator_tag; typename std::enable_if<std::is_convertible<D, D2>::value, bool>::type = bool]' (reversed)
   98 |   operator==(D2 const& rhs) const {
      |   ^~~~~~~~
folly/detail/Iterators.h:84:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator!=(const D&) const [with D = folly::dynamic::const_item_iterator; V = const std::pair<const folly::dynamic, folly::dynamic>; Tag = std::f
orward_iterator_tag]'
   84 |   bool operator!=(D const& rhs) const {
      |        ^~~~~~~~
folly/detail/Iterators.h:103:8: note: candidate: 'bool folly::detail::IteratorFacade<D, V, Tag>::operator!=(const D2&) const [with D2 = folly::dynamic::const_item_iterator; D = folly::dynamic::const_item_iterator; V = const std::pair<const f
olly::dynamic, folly::dynamic>; Tag = std::forward_iterator_tag]'
  103 |   bool operator!=(D2 const& rhs) const {
      |        ^~~~~~~~
```
Pull Request resolved: facebook#1329

Reviewed By: markisaa

Differential Revision: D20458078

Pulled By: yfeldblum

fbshipit-source-id: 15a6a4cfa0f71d45046ee2a13914672b3746b9eb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

3 participants