0

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';
}
user3520616
  • 60
  • 3
  • 17
  • This has the smell of an [X-Y Problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). What real world problem lead you to this possible solution? We can't help you with the problem you've asked, but we may be able to help you with the problem that caused it. – user4581301 Sep 25 '21 at 00:03
  • Because I'd like to get the source location of the caller of the operator. Meanwhile I found a solution. – user3520616 Sep 25 '21 at 00:07
  • Groovy. I'd like to see what you've come up with, so please self-answer. – user4581301 Sep 25 '21 at 00:08
  • did it. it surely is some kind of dirty, but it will do its job – user3520616 Sep 25 '21 at 00:09
  • Thank you. I'm going to play with it a bit and I'll get back to you if there are any little surprises. Well smurf. I can't do that right now. Compiler caps out at C++17 and I can't afford risking breaking anything installing a new one. Wait a second. Thank you Matt Godbolt. – user4581301 Sep 25 '21 at 00:16
  • 1
    Just have `operator[]()` accept an argument of some class/struct type by const reference. That class will need a constructor that accepts (say) an `int` index as first argument, and `std::source_location()` as second argument, defaulted to `std::source_location::current()`. The `operator[]()` can then retrieve both the index and the source location as needed. – Peter Sep 25 '21 at 01:45

1 Answers1

1

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';
}
user3520616
  • 60
  • 3
  • 17
  • That's a pretty wild departure from the usual behaviour of a subscript operator. Not sure what you're going to use this for, but it's probably going to be interesting. – user4581301 Sep 25 '21 at 00:22
  • it's for logging purposes used in debugging. A small wrapper around `std::map` throwing an exception and printing info where there has been an access to an uninitialized value using `operator[]` – user3520616 Sep 25 '21 at 00:27
  • I was pretty sure it would turn out to be a bug hunt. Weren't able to reproduce the problem in a debug build in the lab? Debugger and breakpoint could pinpoint with a lot less effort. – user4581301 Sep 25 '21 at 00:30
  • Side note: If you aren't already headed in this direction, I'd do the logging in `[]` and return something normal so the casual user won't see a thing. – user4581301 Sep 25 '21 at 00:32
  • I need to go Standard diving to see if the default argument will always be set at the callsite. – user4581301 Sep 25 '21 at 00:35
  • 1
    I find nothing. I have to stop looking, but [this](https://stackoverflow.com/questions/5669904/c-default-arguments-in-function-overload-evaluated-once-or-each-time) suggests you'll have consistency and that there is a rule. I just can't find it. – user4581301 Sep 25 '21 at 00:49
  • 1
    Found it. It's really small: http://eel.is/c++draft/dcl.fct.default#2 The little bit right at the end of the highlight declaring equivalency. – user4581301 Sep 25 '21 at 00:57