Q:

Constructors for structs that don't do anything

Edit: Just to be clear, the struct doesn't do anything, as in it has no functions. I think I gave the impression that I thought using an initialiser list and leaving the body of the constructor empty was the issue at hand. 
Say I'm using a struct to hold two values, and I have a constructor just so I can create an arbitrary struct like this:
struct twoValues
{
    int x;
    int y;

    twoValues(int x_, int y_):y(y_),x(x_)
    {}
};

someFunction(twoValues(1,2));

That saves me from having to do this:
twoValues anInstance;
anInstance.x=1;
anInstance.y=2;
someFunction(anInstance);

Edit: You're all correct, I could also initialise with the following:
twoValues anInstance = {1,2};

I see nothing wrong with this but I had some feedback from a C++ test and one of the negative feedback marks was "constructors for structs that don't do anything". I had limited contact with the guy testing me and so never asked why.
Is it a bad thing and why? I would rather carry on doing it.

A:

It depends on what the struct is being used for.  As others have said,
the constructor means that the class is no longer a POD, and that
aggregate initialization cannot be used for it.  In particular, you
cannot have something at namespace scope like:
TwoValues const table[] =
{
    { 1, 2 },
    { 3, 4 },
    // ...
};

You can have:
TwoValues const table[] =
{
    TwoValues(  1, 2  ),
    TwoValues(  3, 4  ),
    // ...
};

but it is more verbose, and it implies dynamic initialization, which may
result in order of initialization issues.
On the other hand, without the constructor, you cannot create temporary
instances on the fly.  Instead of:
extern void f( TwoValues const& );
//  ...

f( TwoValues( 1, 2 ) );

you have to write:
extern void f( TwoValues const& );
//  ...

TwoValues tmp = { 1, 2 };
f( tmp );

If the object is dynamically allocated, it's even worse, since you
either have to allocate first, then initialize, or create a temporary as
above, and then write new TwoValues( tmp ) and use the implicit copy
constructor.
You have to choose.  Depending on what the struct is used for, one or
the other will be preferred; on one hand, I have a lot of structs which
are used exclusively in static tables, and intentionally don't have a
constructor (and contain only types which support static
initialization), and use them a lot for configuring code.  On the other
hand, I also have a lot of structs which are internal to a class, along
the lines of Node in a tree or a graph; these almost always have a
constructor, to facilitate creating them on the fly.  There's no
"correct" answer without knowing the role of the struct in your
application.

A:

Declaring an empty constructor has side-effects..
Even though your constructor has an empty body it is still considered to be a constructor, and therefore certain object properties will be lost - such as the object being POD.
Some cases require the use of Plain Old Data-types, which can make it undesirable to do what you've done without a specific reason.
Read more about initialization without a defult constructor in the next section.

c++03 && c++11
You can initialize your members with values without explicitly defining a "constructor that doesn't do anything", just use the brace-initialization syntax as in the below snippet.
struct Obj {
  int x, y;
};

Obj a = {1,3}; /* a.x = 1, a.y = 2 */

c++03
The downside of not having a constructor is that you cannot initialize the object using  = { ... } in certain circumstances when writing C++03.
C++11 fixes this for you, see the next section for relevant examples.

c++11
In C++11 the initialization using braces ( = { ... }) has been given increased functionality.
As seen in the below snippet where the defined constructor of Obj is called even though we use the same form of initialization as earlier in this post.
struct DoubleBoth {
  DoubleBoth (int x, int y)
    : x(x*2), y(y*2) 
  {}  

  int x, y;
};

The snippets below were all illegal prior to C++11:
DoubleBoth a = {1,2}; /* a.x = 2, a.y = 4 */

struct Wrapper {
  Wrapper ()
    : value {3,4}
  {}

  DoubleBoth value;
};

void func (DoubleBoth v = {1,2}) {  // c++11 only
  ...
}

func ({4,5}); // c++11 only, c++03 requires `DoubleBoth obj (0,1); func (obj);`

A:

You've stopped twoValues from being a POD and have prevented instances of the struct from being default- or value- initialized which are often desirable properties. Personally, I would prefer to have a free function for making temporary instances if you need a simple C++03 friendly approach.
E.g.
twoValues makeTwoValues(int x_, int y_)
{
    twoValues tmp = { x_, y_ };
    return tmp;
}

void f() {
    someFunction(makeTwoValues(1,2));
}

E.g. initializing a member of type twoValues
class X {
    twoValues tv;
public:
    X(int x, int y) : tv(makeTwoValues(x, y)) {}
};

