简体   繁体   English

如何使用 std::enable_if_t 进行完美转发?

[英]How to use std::enable_if_t with perfect forwarding?

I wrote a function receiving a variadic number of std::pairs that subtracts the 2nd element from the 1st element of each pair, and returns a tuple from the newly generated results like this:我编写了一个函数,它接收 std::pairs 的可变数,该函数从每对的第一个元素中减去第二个元素,并从新生成的结果中返回一个元组,如下所示:

template<typename... pairs, std::enable_if_t<((std::is_same_v<std::pair<int, int>, pairs>) && ...)>* = nullptr>
inline constexpr auto foo(pairs&& ...p) noexcept {
    return std::tuple((std::get<1>(std::forward<pairs>(p)) - std::get<0>(std::forward<pairs>(p)))  ...);
}

int main() {
    constexpr auto bar = foo(std::pair(4, 6), std::pair(3, 7), std::pair(1, 2));

    return 0;
}

This works perfectly fine.这工作得很好。 Unless I try to pass it a std::pair that isn't an rvalue, like this:除非我尝试向它传递一个不是右值的 std::pair,如下所示:

int main() {
    constexpr auto tup = std::pair(4, 6);
    constexpr auto bar = foo(tup, std::pair(3, 7), std::pair(1, 2));

    return 0;
}

If I try to do that, I get the following error:如果我尝试这样做,我会收到以下错误:

no matching function for call to 'foo(const std::pair<int, int>&, std::pair<int, int>, std::pair<int, int>)'

How can I pass std::pairs both as lvalue and rvalue references to this function?如何将 std::pairs 作为左值和右值引用传递给此函数? I'm using C++17我正在使用 C++17

When you pass Lvalue, pairs will keep reference in its type, so当您传递 Lvalue 时, pairs将保留其类型的引用,因此

std::is_same_v<std::pair<int, int>, pairs>

results in false.结果为假。

You have to discard reference for example by using std::decay_t :例如,您必须使用std::decay_t丢弃引用:

std::enable_if_t<((std::is_same_v<std::pair<int, int>, std::decay_t<pairs> >) && ...)>* = nullptr

When you pass an lvalue to the function, its corresponding type in the parameter pack is deduced as an lvalue reference due to how forwarding references work.当您将左值传递给函数时,由于转发引用的工作方式,它在参数包中的相应类型被推导出为左值引用 You can use std::decay_t to remove all references and cv-qualifiers prior to your check:您可以在检查之前使用std::decay_t删除所有引用和cv 限定符

std::enable_if_t<((std::is_same_v<std::pair<int, int>, std::decay_t<pairs>>) && ...)>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM