为什么在一行中使用这个C函数两次会导致编译错误?

我试图在Visual C 2010中实现一个与bug in VS in regard to default arguments of template functions相关的智能平等测试宏类型模板函数的麻烦.我通过将参数的值包装在一个额外的函数中来修复它,但现在我发现我不能在一行中使用功能两次!

头文件:

// 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

源文件:

// 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;
}

错误报告如下:

—— 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

违规行是使用逻辑AND来尝试调用smartEqual()两次的行.

我不明白为什么会发生这种情况.将“eps”从引用类型更改为直接值类型可以修复它,但我希望我知道发生了什么.

谢谢!

最佳答案
我想你现在打this VS10 bug.

您的代码在VS11 Beta上编译OK.

通过将smartEqual更改为:可以避免默认值(这似乎是VS10的主要问题)

template<typename T> inline bool smartEqual(
    const T &v1, 
    const T &v2)
{
    return (v1 == v2);
}

并且简单地专门为float(和double)这样做:

template<> bool myspace::smartEqual<float>(
    const float &v1, 
    const float &v2)
{
    return (fabs(v1 - v2) < std::numeric_limits<float>::epsilon());
}

另一个选项是将epsilon参数更改为通过值:

template<typename T> inline bool smartEqual(
    const T &v1, 
    const T &v2, 
    T eps = epsilon<T>())
{
    return (v1 == v2);
}

转载注明原文:为什么在一行中使用这个C函数两次会导致编译错误? - 代码日志