Lost_Arrow's blog

By Lost_Arrow, 5 weeks ago, In English

The GCC 10.2.0 compiler has been in use for a few months now and seems to be pretty stable. It provides most functionalities that were proposed in the C++20 standard among other compilers. This blog is written to bring into the notice of MikeMirzayanov a request for the addition of the compiler for testing and using features from C++20 on here.

You can read more about C++20 features on Wikipedia or any other source.

The compiler can be installed from WinLibs (built by Brecht Sanders) or any other source or even be built from scratch.

Relevant
 
 
 
 
  • Vote: I like it
  • +153
  • Vote: I do not like it

»
5 weeks ago, # |
  Vote: I like it 0 Vote: I do not like it

For people who use PCHs: if you're compiling in Debug mode (with -g flag), you're likely going to face problems compiling programs that you use these PCH's in with cc1plus.exe (the actual compiler) crashing due to its max file size capability being 128 MB. PCHs compiled with -g are going to be nearly 150 MB. One workaround is to not use the -g and simply compile in Release mode (or with the usual -O2) which results in the file size of about 110-ish MB.

»
5 weeks ago, # |
  Vote: I like it +64 Vote: I do not like it

Why are people downvoting this blog? C++20 brings several useful features into competitive programming and support for a newer compiler should definitely be added.

»
5 weeks ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

An off topic question:

auto main () -> int32_t {
  
  return 0;
}

What is the name of this thing (I want to look it up)?

»
5 weeks ago, # |
  Vote: I like it +16 Vote: I do not like it

Samples of C++20 features can found here.

  • »
    »
    5 weeks ago, # ^ |
      Vote: I like it +1 Vote: I do not like it

    Some features (other than concepts and ranges) summarized from link.

    Bit operations C++20 provides a new header which provides some bit operations including popcount.

    std::popcount(0u); // 0
    std::popcount(1u); // 1
    std::popcount(0b1111'0000u); // 4
    

    Math constants Mathematical constants including PI, Euler's number, etc. defined in the header.

    std::numbers::pi; // 3.14159...
    std::numbers::e; // 2.71828...
    

    Structured bindings A proposal for de-structuring initialization, that would allow writing auto [ x, y, z ] = expr; where the type of expr was a tuple-like object, whose elements would be bound to the variables x, y, and z (which this construct declares). Tuple-like objects include std::tuple, std::pair, std::array, and aggregate structures.

    using Coordinate = std::pair<int, int>;
    Coordinate origin() {
      return Coordinate{0, 0};
    }
    
    const auto [ x, y ] = origin();
    x; // == 0
    y; // == 0
    std::unordered_map<std::string, int> mapping {
      {"a", 1},
      {"b", 2},
      {"c", 3}
    };
    
    // Destructure by reference.
    for (const auto& [key, value] : mapping) {
      // Do something with key and value
    }
    

    Immediate functions Similar to constexpr functions, but functions with a consteval specifier must produce a constant. These are called immediate functions.

    consteval int sqr(int n) {
      return n * n;
    }
    
    constexpr int r = sqr(100); // OK
    int x = 100;
    int r2 = sqr(x); // ERROR: the value of 'x' is not usable in a constant expression
                     // OK if `sqr` were a `constexpr` function
    

    Check if associative container has element Associative containers such as sets and maps have a contains member function, which can be used instead of the "find and check end of iterator" idiom.

    std::map<int, char> map {{1, 'a'}, {2, 'b'}};
    map.contains(2); // true
    map.contains(123); // false
    
    std::set<int> set {1, 2, 3};
    set.contains(2); // true
    
    • »
      »
      »
      5 weeks ago, # ^ |
        Vote: I like it +11 Vote: I do not like it

      Isn't structured binding already available in C++17? Source.

      And here is my submission with structured binding : 96330866 (inside the dijkstra function and the two last for loops)

      • »
        »
        »
        »
        5 weeks ago, # ^ |
        Rev. 2   Vote: I like it -8 Vote: I do not like it

        You are right, it was there since C++17. I thought there were some improvements/subtle changes in C++20, but there aren't any changes.

    • »
      »
      »
      5 weeks ago, # ^ |
        Vote: I like it -8 Vote: I do not like it

      Hey, thanks for the quick summary of some of the newest features. I think I'll work on writing a tutorial blog (in a few days maybe, or maybe not) regarding the powerful features we get with C++20 and how to make the best use of it in CP. If you'd like to join me in writing one, hmu with a PM. Also, structured bindings were available pre-C++20 too.

    • »
      »
      »
      5 weeks ago, # ^ |
        Vote: I like it -8 Vote: I do not like it

      std::midpoint for binary search -_-

»
5 weeks ago, # |
  Vote: I like it +13 Vote: I do not like it
  1. three-way comparison with operator <=>

  2. finally you can easily create a set with lambda comparator:

auto cmp = [](int a, int b) { return ... };
std::set<int, decltype(cmp)> s;
  • »
    »
    5 weeks ago, # ^ |
    Rev. 3   Vote: I like it +10 Vote: I do not like it

    Combined:

    std::set <int, decltype([] (int i, int j) { return i <=> j < 0; })> s;
    std::set <int, decltype([] <typename T> (T i, T j) -> bool { return i <=> j < 0; })> s; // why not? :p
    

    I wish the current implementation of the library came with the formatting library proposal (which is basically similar to using Python string power in C++), but sadly it doesn't :'( A few things got postponed to C++23 too

  • »
    »
    5 weeks ago, # ^ |
    Rev. 2   Vote: I like it +3 Vote: I do not like it

    set with lambda comparator works in C++17(maybe C++14) too, if you pass the comparator to the constructor.

    auto cmp = [](int a, int b) { return ... };
    std::set<int, decltype(cmp)> s(cmp);
    
    • »
      »
      »
      5 weeks ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      I know, but why should I write cmp twice?

»
5 weeks ago, # |
Rev. 2   Vote: I like it +8 Vote: I do not like it

This blog reminds me that topcoder is still on C++14 (or 11?), and atcoder supports C++17 only from this year...

»
5 weeks ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

Is there any work around to the fact that most functions in std::ranges conflict with std

For example

#include <bits/stdc++.h>
using namespace std;
using namespace std::ranges;
int main(){
    int n;
    cin>>n;
    vector<int> seq(n);
    for(auto &x : seq) cin>>x;
    sort(seq);
    for(auto &x : seq) cout<<x<<" ";
}
  • »
    »
    5 weeks ago, # ^ |
    Rev. 2   Vote: I like it 0 Vote: I do not like it

    I don't think there is any easy workaround that allows this. The reason why the C++20 library was implemented in a separate namespace altogether is to not break existing codebases with name clashes.

    Maybe you'd have to get used to something like (or let's take the advice of real software developers and not use using namespace ...; :p):

    namespace r = std::ranges;
    
    auto main () -> int32_t {
    	int r; // no name clash here
    	std::cin >> r;
    	std::vector <int> v (r);
    	read(v);
    	r::sort(v);
    	write(r);
    }
    
»
5 weeks ago, # |
  Vote: I like it 0 Vote: I do not like it

Since constexpr was made much more powerfull, what would be the constraints on compiletime.

In my understanding currently there is no compile time limit, but I think we would need one.

  • »
    »
    5 weeks ago, # ^ |
    Rev. 2   Vote: I like it +5 Vote: I do not like it

    AFAIK, you'll need additional compilation flags to increase the constexpr loop limits. I just wrote a constexpr sieve of eratosthenes program to check and this seems to be true.

    ||=== Build: Release in Template (compiler: GNU GCC Compiler) ===|
    main.cpp||In function 'int main()':|
    main.cpp|117|error: 'constexpr' loop iteration count exceeds limit of 262144 (use '-fconstexpr-loop-limit=' to increase the limit)|
    ||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 2 second(s)) ===|
    

    Although constexpr has gotten stronger in many aspects, it's still mostly useless to CP in terms of precomputing large amount of "stuff" due to in-built limits and neither can we change compilation flags on OJs AFAIK to increase the limit. Also, maybe you could say that constexpr std::vector/string could fasten up probable TLE's when computation happens at runtime instead but no existing compiler supports them with constexpr yet nor are problem time limits decided in a way that you can't solve them without it.