[英]C++ template function unused typename
我試圖了解 C++ 模板並復制語義。 我明白為什么我不能調用assign1
(它要求右值引用並且我提供了一個左值引用)但是為什么我可以調用具有相同約束的assign2
?
template<typename... Args>
void assign1(Args&& ... arguments) { }
template<typename A, typename... Args>
void assign2(Args&& ... arguments) { }
template<typename A, typename B, typename... Args>
void assign3(Args&& ... arguments) { }
int main() {
const int r = 2;
assign1<int>(r); // no matching function for call to...
assign2<int>(r); // ok!
assign3<int>(r); // no matching function for call to...
}
給定assign1<int>(r);
,您明確指定模板參數,那么assign1
的參數類型將是int&&
,正如您所說,它是右值引用,不能與左值綁定。
給定assign2<int>(r);
,您將第一個模板參數A
指定為int
,參數包Args
將從 function 參數r
推導出來。 請注意,它不是 rvalue-reference 而是forwarding reference ,它可以同時接受左值和右值。 (根據function arguments是左值還是右值,根據類型推導結果,function參數類型為左值引用或rvalue-reference)。
給定assign3<int>(r);
,您僅指定第一個模板參數A
,但無法從 function 參數推導出第二個參數參數B
並且調用失敗。
如果你想讓 function 模板只接受右值,你可以添加static_assert
像
template<typename A, typename... Args>
void assign2(Args&& ...) {
static_assert(((!std::is_lvalue_reference_v<Args>) && ...), "must be rvalue");
}
或申請SFINAE 。
template<typename A, typename... Args>
std::enable_if_t<((!std::is_lvalue_reference_v<Args>) && ...)> assign2(Args&& ...) {
}
或者添加另一個采用左值引用的重載並將其標記為delete
。 (此方法僅在所有 arguments 都是左值時才有效。)
template<typename A, typename... Args>
void assign2(Args& ... arguments) = delete;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.