Search code examples
c++operator-overloadingsubscript-operatorstd-source-location

operator[] caller's site source location current workaround


sadly, the current source location can't be used directly in the parameter list of operator[], as this operator has to have only one argument. However, is there a workaround so I can get the callers source line? Consider this code for example:

#include <iostream>
#include <string>
#include <source_location>


struct Test
{
  std::source_location src_clone(std::source_location a = std::source_location::current())
  {
    return a;
  }
    
  //this doesnt work:
  //auto operator[](int a, std::source_location src_clone = std::source_location::current())
  auto operator[](int a)
  {
    return std::source_location::current();
  }
};

int main()
{
  auto t = Test{};
    
  auto s1 = t.src_clone();
  std::cout << s1.line() << ' ' << s1.function_name() << '\n';
    
  // is there a way to make this print "main.cpp:30"?
  auto s0 = t[5];
  std::cout << s0.line() << ' ' << s0.function_name() << '\n';
}

Solution

  • Found a solution:

    #include <iostream>
    #include <string>
    #include <source_location>
    #include <string_view>
    #include <concepts>
    
    struct string_like
    {
      std::string_view strView;
      std::source_location s;
        
      template <typename T>
      string_like (T strView, std::source_location s = std::source_location::current())
        requires std::constructible_from<std::string_view, T>
        : strView(strView), s(s) {}
    };
    
    struct Test
    {
      auto operator[](string_like s)
      {
        return s.s;
      }
    };
    
    int main()
    {
      auto t = Test {};
      auto s0 = t["hello"];
     
      // prints main.cpp:29 as it should
      std::cout << s0.line() << ' ' << s0.function_name() << '\n';
    }