Albanians
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Spaceship Operator And Argument-Dependent Lookup Explained ## Spaceship Operator In C++ you can define your own comparison operators, but there is also a way to do all the comparisons with one of them which is the spaceship operator. Comparisons depend on the type of the object, and sometimes we need to use functions that only the object has. That's where ADL is needed. The spaceship operator, also known as the three-way comparison operator, is a binary operator used in some programming languages to perform a three-way comparison between two values. It is typically represented by the symbol <=>. The result of the comparison can be used to determine whether one value is less than, equal to, or greater than another. When the spaceship operator is used then it will return one of four enums: - equivalent - greater - less - unordered -> only when the comparison isn't clear ## Spaceship Operator Ordering To understand the spaceship operator we first need to understand how the ordering of elements goes. There are different types of ordering like: - Strong ordering - Weak ordering - Partial ordering The next section shows the result of the <=> operator implemented in a way to demonstrate the differences of the ordering types. ### Strong Ordering Strong ordering exists when a set of elements can be unambiguously arranged in a specific sequence based on a well-defined comparison criterion. In a strongly ordered set, any two distinct elements can be compared, and the result is always deterministic—indicating whether one element is less than, equal to, or greater than the other. This clear and consistent arrangement ensures predictability and reliability when working with ordered collections or data structures. For example there are 2 objects of type int which are named a and b. We would like to know if a is greater than, less than or equal to b. ```c++ std::string comparing_integer_strong_ordering(int a, int b){ // A simple if-clause to check integers and wether a is equal to, greater than or less than b if(a == b){ return "equal to"; } else if (a > b){ return "greater than"; } else{ return "less than"; } } int main(){ int a = 5; int b = 6; // Expected result: "less than" std::cout << "Strong ordering comparison with integers: a is " << comparing_integer_strong_ordering(a,b) << " b" << std::endl; } ``` Result: ``` Strong ordering comparison with integers: a is less than b ``` In the code above, the function comparing_integer_strong_ordering takes two integer parameters, a and b, and compares them using a strong ordering logic. The function returns a string indicating whether a is equal to, greater than, or less than b. The main function initializes two integers, a and b, with values 5 and 6, respectively. It then calls the comparing_integer_strong_ordering function and prints the result, which is the relationship between a and b based on the strong ordering comparison. In this specific example, the expected result is "less," as a (5) is less than b (6). ### Weak Ordering Weak ordering is a little different in comparison to strong ordering. When using weak ordering it also returns either greater(>), less than(<) or equivalent. The main difference between weak and strong ordering is that two different objects can be considered the same even though they are different. As an example there are 2 object of type string a and b which both store the same word "apple" one is stored with an uppercase "A" and one with a lowercase "a". ```c++ std::string comparing_strings_weak_ordering(std::string a, std::string b){ // Using std::transform to change the strings to have lowercase charachters std::transform(a.begin(), a.end(), a.begin(),[](unsigned char c){ return std::tolower(c);}); std::transform(b.begin(), b.end(), b.begin(),[](unsigned char c){ return std::tolower(c);}); // Using the "strcmp" to compare the strings given int result = std::strcmp(a.c_str(),b.c_str()); if(result == 0){ return "equal to"; } else if(result > 0){ return "greater than"; } else{ return "less than"; } } int main(){ std::string a_string = "apple"; std::string b_string = "Apple"; // Expected result: "equal to" std:: cout << "Weak ordering comparison with strings: a_string is "; std::cout << comparing_strings_weak_ordering(a_string, b_string) << " b_string" << std::endl; } ``` Result: ``` Weak ordering comparison with strings: a_string is equal to b_string ``` In this code, the function comparing_strings_weak_ordering takes two std::string parameters, a and b. The function first converts both strings to lowercase using std::transform and std::tolower to ensure a case-insensitive comparison. Then, it uses the C library function std::strcmp to compare the two strings. The result of the comparison is stored in the variable result. Finally, based on the value of result, the function returns a string indicating whether the strings are equal, greater than, or less than each other. In the main function, two strings, a_string and b_string, are initialized with values "apple" and "Apple," respectively. The comparing_strings_weak_ordering function is called with these strings, and the expected result is "equal to" since the comparison is case-insensitive, and the transformed strings are the same. The result is then printed to the console. ### Partial Ordering Partial ordering occurs when not all elements in a set are comparable. In a partially ordered set, some elements may be comparable, providing a clear ordering relationship, while others might lack a defined relationship. This flexible arrangement allows for a partial hierarchy, with certain pairs of elements having an order, while others remain unordered or incomparable. For example there are 2 objects of type std::tuple which are named a_tuple and b_tuple. We would like to know if a_tuple is greater than, less than or equal to b_tuple. ```c++ std::string comparing_tuples_partial_ordering(std::tuple<int,int> a, std::tuple<int,int> b){ /* * Before we do any comparing we have to check if there is the same int in the same spot of the two tuples * We do that in the first if-else statement */ // This is the case where the first int of the two tuples is the same if(std::get<0>(a) == std::get<0>(b)){ // In this if-else statement we compare the second integer of the tuples if (std::get<1>(a) < std::get<1>(b)) return "less than"; else if (std::get<1>(a) > std::get<1>(b)) return "greater than"; else if (std::get<1>(a) == std::get<1>(b)) return "equal to"; } // This is the case where the second int of the two tuples is the same else if(std::get<1>(a) == std::get<1>(b)){ // In this if-else statement we compare the first integer of the tuples if (std::get<0>(a) < std::get<0>(b)) return "less than"; else if (std::get<0>(a) > std::get<0>(b)) return "greater than"; else if (std::get<0>(a) == std::get<0>(b)) return "equal to"; } /* * If none of the numbers are the same we can't do any comparison and we return undefined * When you cant define a return statement for comparison then that means that the * compare function has partial ordering */ return "undefined"; } int main(){ // Tuples to show partial order comparison std::tuple<int,int> a_tuple = {1,2}; std::tuple<int,int> b_tuple = {3,4}; // You can see that the output is undefined std:: cout << "Partial ordering comparison with tuples: a_tuple is "; std::cout << comparing_tuples_partial_ordering(a_tuple,b_tuple) << " b_tuple" << std::endl; a_tuple = {1,2}; b_tuple = {1,4}; // Here you can see that we can compare because the tuples have the same integer in the same spot std:: cout << "Partial ordering comparison with tuples: a_tuple is "; std::cout << comparing_tuples_partial_ordering(a_tuple,b_tuple) << " b_tuple" << std::endl; } ``` Result: ``` Partial ordering comparison with tuples: a_tuple is undefined b_tuple Partial ordering comparison with tuples: a_tuple is less than b_tuple ``` In this code, the function comparing_tuples_partial_ordering takes two tuples, a and b, each containing tuples. The function first checks if the first integers in the tuples are the same. If they are, it proceeds to compare the second integers to determine whether a is less than, equal to, or greater than b. If the first integers are different, it checks if the second integers are the same and compares the first integers in the same way as mentioned above. If neither condition is met, meaning the tuples have no common integers in the same positions, the function returns "undefined," indicating that a comparison cannot be made, demonstrating partial ordering. In the main function, two tuples, a_tuple and b_tuple, are initialized with values {1,2} and {3,4}. Since these tuples have no common integers in the same positions, the result of the first comparison is "undefined." In the second part of the main function, a_tuple and b_tuple are updated to {1,2} and {1,4}, respectively. Now, the tuples have a common integer (1) in the same position, allowing for a partial ordering comparison. The result is then printed to the console. ### Compilers results You can also use the already implemented spaceship operator to do the same comparisons. There are some differences in the results. For example if we try to compare the same tuples as earlier with the implemented spaceship operator the result will be that a_tuple is less than b_tuple. ```c++ int main() { // Tuples to show partial order comparison from the compiler std::tuple<int,int> a_tuple = {1,2}; std::tuple<int,int> b_tuple = {3,4}; // Here we store the result of the compilers comparison of two tuples std::partial_ordering c_tuple_result = c_a_tuple <=> c_b_tuple; std::cout << "Compilers result for comparing tuples with partial ordering: "; if (c_tuple_result == std::partial_ordering::less) { std::cout << "Less" << std::endl; } else if (c_tuple_result == std::partial_ordering::equivalent) { std::cout << "Equal" << std::endl; } else if (c_tuple_result == std::partial_ordering::greater){ std::cout << "Greater" << std::endl; } else if (c_tuple_result == std::partial_ordering::unordered){ std::cout << "Unordered" << std::endl; } } ``` Result: ``` Compilers result for comparing tuples with partial ordering: Less ``` This happens because the spaceship operator for comparing tuples is implemented in a different way compared to the one showed earlier. The one showed earlier was created like that only to demonstrate partial ordering, but there is an actual way of creating strong ordering for comparing tuples also, which is what the compiler uses. ## Argument-Dependent Lookup Argument-dependent lookup (ADL), also known as "argument-dependent name lookup" or "Koenig lookup," is a feature in the C++ programming language that affects how the compiler searches for the names of functions and operators in expressions. ADL is particularly relevant when dealing with function overloading and namespaces. Here's a brief explanation of how ADL works: Normal Name Lookup: - The compiler first looks for the function or operator in the scope where it is called. - If the name is not found in that scope, the compiler looks in outer scopes and in the global scope. Argument-Dependent Lookup (ADL): - If the function or operator is not found through normal name lookup, ADL includes the namespaces associated with the types of the function arguments. - The compiler looks for the function or operator in the namespaces of the function arguments. Here is an example to demonstrate ADL: ```c++ #include <iostream> namespace A { struct MyType {}; void foo(MyType mt) { std::cout << "A::foo called" << std::endl; } } namespace B { void foo(int i) { std::cout << "B::foo called" << std::endl; } } int main() { A::MyType obj; foo(obj); // Calls A::foo due to ADL, even though 'foo' is not in the scope. return 0; } ``` In this example, the foo function is called with an argument of type A::MyType. Even though foo is not in the same scope as the function call, ADL allows the compiler to find the function in the namespace A, where the argument type is declared. Therefore, A::foo is called. ADL is particularly useful in generic programming scenarios where the types are not known in advance. It allows functions to be found in the namespaces associated with the argument types, providing a way to extend functionality without modifying existing code. ## References geeksforgeeks: - https://www.geeksforgeeks.org/3-way-comparison-operator-space-ship-operator-in-c-20/ cppreference: - https://en.cppreference.com/w/cpp/language/default_comparisons - https://en.cppreference.com/w/cpp/language/adl

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully