Search code examples
c++c-preprocessorc++20template-meta-programming

C++ Separate different instances of a class at compile time


What are available options to separate different instances of a class at compile time?

I basically want the following code snippet to compile without errors:

struct equal_ret_t {};
struct different_ret_t {};

struct Foo
{
    Foo() = default;
    // ... add relevant code here
};

constexpr auto eval(Foo const& a, Foo const& b)
{
    // return equal_ret_t for same instances,
    // different_ret_t for different instances
}

int main()
{
    Foo a;
    Foo b;
    static_assert(std::is_same_v<decltype(eval(a,a)),equal_ret_t>);
    static_assert(std::is_same_v<decltype(eval(b,b)),equal_ret_t>);
    static_assert(std::is_same_v<decltype(eval(a,b)),different_ret_t>);
}

What is the required code to add to the Foo class and/or the eval function?

Are there any solutions approved by the current C++20/23 standard? If not, can the solution made portable across major compilers?


Solution

  • You will not be able to achieve the exact syntax you expect to use, but here's something that may be close enough for your purposes:

    #include <type_traits>
    
    struct Foo {
      constexpr bool operator==(const Foo &other) const {
        return this == &other;
      }
    };
    
    struct equal_ret_t {};
    struct different_ret_t {};
    
    template <bool Equal>
    using ret_t = std::conditional_t<Equal, equal_ret_t, different_ret_t>;
    
    int main() {
      Foo a;
      Foo b;
      static_assert(std::is_same_v<ret_t<a == a>, equal_ret_t>);
      static_assert(std::is_same_v<ret_t<b == b>, equal_ret_t>);
      static_assert(std::is_same_v<ret_t<a == b>, different_ret_t>);
    }
    

    Try it on Compiler Explorer