C++模板函数未使用的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将从函数参数r推导出来。注意,它不是右值引用,而是转发引用,它可以同时接受左值和右值。(根据函数参数是左值还是右值,根据类型推导结果,函数参数类型将是左值引用或右值引用。(

给定assign3<int>(r);,您只指定了第一个模板参数A,但第二个参数B无法从函数参数推导出来,调用失败。


如果你想让函数模板只接受右值,你可以像一样添加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。(只有当所有参数都是左值时,这种方法才有效。(

template<typename A, typename... Args> 
void assign2(Args& ... arguments) = delete;

实时

相关内容

  • 没有找到相关文章

最新更新