簡體   English   中英

當使用 function 調用模板函數時,我遇到了一個意外的匹配模板 function 進行調用

[英]When using function calls to template functions, I am faced with an unexpected matching template function for my call

對於以下代碼,為什么編譯器匹配我的 function 調用與(意外)模板 function:

首先是可用的 function 模板:

// First function template
template <typename T, typename U>
auto sub(T x, U y) {
    return x - y;
}

// Second function template
template <typename T>
auto sub(T x, T y) {
    return x - y;
}

現在假設我從一個模板參數推導語句開始:

sub(5.2, 2.1);

上面的語句應該反過來使用上面提供的第二個 function 模板實例化一個 function 實例(模板函數),最終看起來像這樣:

template<>
double sub<double>(double x, double y) {
    return x - y;
}

下一條語句不會實例化新模板 function,因為它將能夠與之前創建的模板匹配。

sub<double>(2.3, 234.2);

現在下面的陳述是我有點困惑的地方。

sub<double>(2.3, 234.0f); // Weird one

盡管我提供了一個實際類型(double),但在模板參數中,我遇到了一個奇怪的結果。 我故意將第二個 function 參數設置為浮點數,以便與我們之前提到的 function 實例(模板函數)不完全匹配,並且預期會發生浮點提升並將浮點數提升為雙精度值,然后匹配模板 function ,這不是最終發生的事情......而是它使用頂部提供的第一個 function 模板創建了一個新的 function 實例(模板函數),最終看起來像這樣:

template<>
double sub<double, float>(double x, float y) {
    return x - y;
}

我感到困惑的是,我如何認為編譯器更喜歡促銷而不是這樣的東西,或者我可能把它與其他東西混淆了,我希望有人可以澄清一下。

也困擾我的一個問題是,我不知道如何才能顯式調用我真正想要的模板 function,例如:

sub<double>(2, 2);

如果我希望它調用模板 function 並且兩個參數類型都是double並且只是希望我的 arguments 都從int數字轉換為double怎么辦。 按照這個邏輯,我不能這樣做,因為編譯器最終會創建一個新的 function 實例(模板函數),它看起來像這樣:

template<>
double sub<double, int>(double x, int y) {
    return x - y;
}

我必須提到我不是在談論如何轉換我的 arguments 因為我很清楚我可以在它們上使用static_cast ,我也不是在談論做這樣的事情:

sub<double, double>(2, 2);

As that would of course, use the first function template to create a new function instance (template function), not use the already available template function (which was created through the use of the second function template ). 如果真的有辦法,有人可以解釋我怎么能做到嗎? 所有這一切,主要是因為我試圖真正理解概念。

您可以提供模板參數的部分列表。 例如,如果您有

template <typename A, typename B, typename C>
void foo(A, B, C);

然后這些電話

foo(1,2,3);
foo<int>(1,2,3);
foo<int, double>(1,2,3);
foo<int, double, float>(1,2,3);

都很好。

所以sub<double>(2.3, 234.2f); 仍然匹配第一個 function 模板和第二個模板的實例化,前者更好匹配,因為它不需要轉換。 只有當兩個匹配都同樣好時,重載決議才更喜歡非模板而不是模板1 如果模板更匹配,則使用它。

當兩個參數的類型不同時,可以強制選擇第二個模板:

auto x = (static_cast<float(*)(float, float)>(sub))(1, 2.0);

但這當然違背了目的。 為了方便使用,你需要引入一些其他的選擇機制,例如

enum class same { type };
template <typename T, same = same::type>
auto sub(T x, T y)...

... sub<double, same::type>(2.3, 234.0f) ...

1或者更確切地說,需要推導模板參數的調用與不需要推導任何內容的調用。

暫無
暫無

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

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