3

I am using clang to compile my code using the c++14 dialect. Take the following example:

class x
{
    int _i;

public:

    x(int i)
    {
        this->_i = i;
    }
};

void x()
{
}

void f(class x my_x)
{
    // Do something here
}

int main()
{
    /*
     f(x(33)); // Doesn't work
     f(class x(33)); // Doesn't work
    */

    // This works:

    class x my_x(33);
    f(my_x);

    typedef class x __x;
    f(__x(33));
}

Here I have a class named x whose name conflicts with a function with the same name. To distinguish between x the class and x the function, one has to use the class identifier. This works for me in all situations, but I could never find a way to directly call the constructor for x.

In the previous example, I want to provide function f with an x object by building it on the go. However, if I use f(x(33)) it interprets it as an ill-formed call to the function x, and if I use f(class x(33)) it just yields a syntax error.

There are obvious workarounds, but I would like to know if there is anything more elegant than typedefing the class x with a temporary alias or explicitly instantiating an item that will annoy me by living in the whole scope of the calling function while I need it only in the line of the function call.

Maybe there is a simple syntax that I am not aware of?

Matteo Monti
  • 8,362
  • 19
  • 68
  • 114
  • Not immediately relevant, and plus one for good question, but `typedef class x __x;` is undefined due to double underscore before x. – Bathsheba Jul 28 '15 at 11:32
  • What do you mean by undefined? That code compiles for me. I am always using classes that begin with double underscore... am I doing something wrong? – Matteo Monti Jul 28 '15 at 11:34
  • 3
    See http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier. Have an enjoyable afternoon refactoring. – Bathsheba Jul 28 '15 at 11:38

1 Answers1

9

All you need is a pair of parentheses:

f((class x)(33));

Or for more parameters, also use uniform initialization:

f((class x){1, 2, 3});
StenSoft
  • 9,369
  • 25
  • 30
  • Yay!! That was easy. Thanks a lot! – Matteo Monti Jul 28 '15 at 11:36
  • Oh. Wait. But this works only with single argument constructors. Is there a way to get this working on multiple argument constructors as well? – Matteo Monti Jul 28 '15 at 11:49
  • @MatteoMonti Make a typedef for `class x` and use a function style cast `T(a,b,c)` – David G Jul 28 '15 at 12:03
  • @MatteoMonti Use uniform initialization: `f((class x){1, 2, 3})`, `(1, 2, 3)` will invoke comma operator. – StenSoft Jul 28 '15 at 12:08
  • @StenSoft Wouldn't that create a designated initializer which is only supported in modern C++ compilers as an extension? – David G Jul 30 '15 at 01:31
  • @0x499602D2 No, [designated initializers](https://en.wikipedia.org/wiki/C_syntax#Designated_initializers) are, well, designated (eg. `{ .x = 1, .y = 2}`). – StenSoft Jul 30 '15 at 02:37