Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function with default argument doesn't compile with VC++, but does with g++ and clang

Tags:

c++

templates

I've searched this site and cannot find a solution to my problem. I have reduced my sample code down as much as I think I can while still retaining the relevant error. I am left with the following two files:

test.hpp

namespace models {

template<typename FloatingPoint>
class ellipsoid {
  public:
    explicit ellipsoid(FloatingPoint = 6378137.0);
  private:
    FloatingPoint a_;
};

template<typename FloatingPoint>
ellipsoid<FloatingPoint>::ellipsoid(FloatingPoint a) : a_(a) {}

}  // End namespace models


// Function declaration
template<typename FloatingPoint>
FloatingPoint compute(FloatingPoint,
                      const models::ellipsoid<FloatingPoint>& =
                          models::ellipsoid<FloatingPoint>());

// Function definition
template<typename FloatingPoint>
FloatingPoint compute(FloatingPoint x,
                      const models::ellipsoid<FloatingPoint>& model) {

    return 3.14;
}

test.cpp

#include "test.hpp"

int main() {
    compute(10.0);
    return 0;
}

When I compile the above code using VC++ 2017, I get the following error:

error C2512: 'models::ellipsoid<FloatingPoint>': no appropriate default constructor available
note: No constructor could take the source type, or constructor overload resolution was ambiguous

Both clang and g++ compile this without a problem. Also, if I remove the ellipsoid class from the namespace models, and remove the models:: invocations in the compute function, it then compiles fine using VC++. Is this a bug within the VC++ compiler, or have I got a bug in my code?

like image 632
Regan Tackett Avatar asked May 20 '17 23:05

Regan Tackett


1 Answers

This was a bug in VC++, which was fixed in Visual Studio 2019 since compiler version 19.23. Demo: https://gcc.godbolt.org/z/a5TxPa8ac

like image 156
Fedor Avatar answered Oct 15 '22 00:10

Fedor