0

To avoid complexity, below is a minimal example. For some reason, I have to pass normal object as const to some method and use it as such:

#include<iostream>
#define CALL(OBJECT, METHOD) \
    const_cast<std::remove_const_t<std::remove_reference_t<decltype(OBJECT)>>&>(OBJECT).METHOD()

struct X { void foo () { std::cout << "X::foo()\n"; } };
int main ()
{
  const X x;
  CALL(x,foo);
}

Above code compiles fine for g++ & clang++. However with MSVC compiler it results in below error:

Left of .foo() must have a class/struct/union

Is this a compiler bug? What can be a workaround fix within that macro?

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • All compile fine [here](https://godbolt.org/z/9999PKjc4). – Jarod42 Jan 10 '22 at 15:23
  • 3
    BTW, you might remove MACRO to simplify example. – Jarod42 Jan 10 '22 at 15:25
  • 1
    You need "Share" a snippet to get a permalink. The browser address you give here is to the default landing page. – StoryTeller - Unslander Monica Jan 10 '22 at 15:25
  • @Jarod42, somehow in my system MSVC2019 64-bit, along with Qt. Above error is reproducing. Which compiler is in godbolt? – iammilind Jan 10 '22 at 15:27
  • @StoryTeller-UnslanderMonica, sorry I just referred it. But in reality, what I saw was a runtime error as seen [here](https://godbolt.org/z/bT4r1qccW). In any case in my local system, above error comes. – iammilind Jan 10 '22 at 15:28
  • There are a big possible selection of compiler version by compiler (I tend to test with latest, but not trunk). – Jarod42 Jan 10 '22 at 15:29
  • `const_cast(x).foo();` would be simpler. – Jarod42 Jan 10 '22 at 15:33
  • 2
    Notice that you have UB if `X::foo` does modify itself, as modifying const object is UB. – Jarod42 Jan 10 '22 at 15:36
  • @Jarod42, the actual code is lot more complex than the above example. After lots of trial and error and referring [this answer](https://stackoverflow.com/a/15887250), I have arrived to this solution, which works in all the platforms. Even in MSVC, it gives a spurious error, whch is not supposed to be. Regarding *UB*, the above code is only for demo purpose. In reality, a non-const object is passed as `const` at some places and then required to be called with the said method in special cases. So the source object is mutable. – iammilind Jan 11 '22 at 02:58

0 Answers0