簡體   English   中英

為什么在一行中兩次使用此C ++函數會導致編譯錯誤?

[英]Why does using this C++ function twice in one line cause a compile error?

我試圖在Visual C ++ 2010中實現智能相等測試宏類型模板函數時遇到了一些麻煩,該函數與VS中關於模板函數的默認參數的錯誤有關 我通過在額外的函數中包裝參數的值來修復它,但現在我發現我不能在一行中使用該函數兩次!

頭文件:

// 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 build:項目:測試,配置:調試Win32 ------
TEST.CPP
c:\\ users \\ ninja \\ documents \\ visual studio 2010 \\ projects \\ test \\ test \\ test.cpp(24):錯誤C2440:'default argument':無法從'const float *'轉換為'const float&'
原因:無法從'const float *'轉換為'const float'
沒有可以進行此轉換的上下文

違規行是我嘗試使用邏輯AND兩次調用smartEqual()的行。

我不明白為什么會這樣。 將“eps”從引用類型更改為直接值類型可以修復它,但我希望我知道發生了什么。

謝謝!

我想你現在已經遇到了這個VS10漏洞

您的代碼在VS11 Beta上編譯正常。

您可以通過將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);
}

代碼在VS2010中失敗,但在英特爾編譯器中沒問題。 看起來像VS2010中的一個bug

經過一番考慮后,我決定采用@Fraser建議的另一種解決方案(雖然我從他那里得到了靈感)並寫下我自己的答案:

  1. 第一個解決方案讓我無法靈活地使用自定義的eps值。
  2. 帶有pass-by-value的第二個解決方案感覺不對,特別是如果將來我決定將這個函數用於一些更人為的類型。

由於VS似乎覆蓋了關於參數默認值的錯誤(僅在模板中?),似乎最明智的做法是通過創建兩個版本的smartEqual來回避問題; 有和沒有eps(使用默認值),這幾乎做同樣的事情,如果不是簡潔:

// An equality test that doesn't require the value of eps, default will be used
template<typename T> inline bool smartEqual(
    const T &v1, 
    const T &v2)
{
    return (v1 == v2);
}

// Float specialization: return (fabs(v1 - v2) < std::numeric_limits<float>::epsilon());
template<> inline bool smartEqual<float>(
    const float &v1, 
    const float &v2);

// A custom-eps value equality test
template<typename T> inline bool smartEqual(
    const T &v1, 
    const T &v2, 
    const T &eps)
{
    return (v1 == v2);
}

// Float specialization: return (fabs(v1 - v2) < eps);
template<> bool smartEqual<float>(
    const float &v1, 
    const float &v2, 
    const float &eps);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM