foo x=foo() is copy initialization, 
Initializes an object from another object
and foo() is value initialization.
This is the initialization performed when a variable is constructed with an empty initializer. 
foo x={} is aggregate initialization.
Initializes an aggregate from braced-init-list 
If the number of initializer clauses is less than the number of
  members and bases (since C++17) or initializer list is completely
  empty, the remaining members and bases (since C++17) are initialized
  by their default initializers, if provided in the class definition,
  and otherwise (since C++14) by empty lists, which performs
  value-initialization.
So the result is the same in this case (both value-initialized).
And the effects of value initialization in this case are: 
if T is a class type with a default constructor that is neither user-provided nor deleted (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized
Finally the effects of zero initialization in this case are:
If T is a scalar type, the object's initial value is the integral
  constant zero explicitly converted to T. 
If T is an non-union class type, all base classes and non-static data
  members are zero-initialized, and all padding is initialized to zero
  bits. The constructors, if any, are ignored.