Why does using this C++ function twice in one line cause a compile error?
c++, default-arguments, type-conversion, visual-studio
Solution
I think you've now hit this VS10 bug.
Your code compiles OK on VS11 Beta.
You could possibly avoid the default value (which seems to be a major issue for VS10) by changing `smartEqual` to:
template<typename T> inline bool smartEqual(
const T &v1,
const T &v2)
{
return (v1 == v2);
}
and simply specialising for float (and double) like this:
template<> bool myspace::smartEqual<float>(
const float &v1,
const float &v2)
{
return (fabs(v1 - v2) < std::numeric_limits<float>::epsilon());
}
Another option is to change the epsilon parameter to pass by value:
template<typename T> inline bool smartEqual(
const T &v1,
const T &v2,
T eps = epsilon<T>())
{
return (v1 == v2);
}
Problem
I ran into some trouble trying to implement a smart equality test macro-type template function in Visual C++ 2010 that had to do with a bug in VS in regard to default arguments of template functions. I fixed it by wrapping the value of the parameter in an extra function, but now I found that I can't use the function twice in one line! Header file: ``` // example.h #pragma once #include <limits> namespace myspace { // Need to define this separately to avoid a Visual Studio bug template<typename T> T epsilon() { return std::numeric_limits<T>::epsilon(); } // A generic equality test template<typename T> inline bool smartEqual( const T &v1, const T &v2, const T &eps = epsilon<T>()) { return (v1 == v2); } // Template specialization for floating-point numbers template<> bool smartEqual<float>( const float &v1, const float &v2, const float &eps); } // namespace myspace ``` Source file: ``` // example.cpp #include "example.h" using namespace std; using namespace myspace; // equal-macro specialization for floats using epsilon template<> bool myspace::smartEqual<float>( const float &v1, const float &v2, const float &eps) { return (fabs(v1 - v2) < eps); } int _tmain(int argc, _TCHAR* argv[]) { float a,b; bool x = smartEqual(a,b); // works ok bool x = smartEqual(a,b) && smartEqual(b,a); // error return 0; } ``` The error is reported as follows: ------ Build started: Project: test, Configuration: Debug Win32 ------ test.cpp c:\users\ninja\documents\visual studio 2010\projects\test\test\test.cpp(24): error C2440: 'default argument' : cannot convert from 'const float *' to 'const float &' Reason: cannot convert from 'const float *' to 'const float' There is no context in which this conversion is possible The offending line is the one where I try to call smartEqual() twice using the logical AND. I don't understand why this happens. Changing "eps" from a reference type to a straightforward value type fixes it, but I wish I knew what was going on. Thanks!