函数模板正确定义前向引用数组和元素类型

问题描述 投票:0回答:1

最小工作示例:

#include <array>
#include <iostream>

template <typename T> struct is_array : std::false_type {};
template <typename U, std::size_t N> struct is_array<std::array<U, N>> : std::true_type {};

template <typename T>
std::enable_if_t<is_array<std::decay_t<T>>::value>
do_something_prob(T&& arr, typename T::value_type mul)  // `arr` becomes an rvalue?
{
    for (auto && v : arr)
        std::cout << v * mul << '\n';
}

template <
    typename T, 
    typename ElemT = std::enable_if_t<is_array<std::decay_t<T>>::value, typename T::value_type>
>
void do_something_no_prob(T&& arr, ElemT mul)
{
    for (auto && v : arr)
        std::cout << v * mul << '\n';
}

int main()
{
    auto arr = std::array<int, 3>{1, 2, 3};
    
    do_something_prob(std::array<int, 3>{1, 2, 3}, 2);
    // do_something_prob(arr, 2);  // error message: 'std::array<int, 3>&' is not a class, struct, or union type'

    do_something_no_prob(std::array<int, 3>{1, 2, 3}, 2);
    do_something_no_prob(arr, 2);
}

我想要实现什么:实现一个接受两个参数的函数模板,(1)对任何数组类型的前向引用和(2)与数组元素相同类型的副本。

这是通过

do_something_no_prob
实现的。但
do_something_prob
有什么问题呢?它无法处理左值。

c++ c++17 sfinae forwarding-reference
1个回答
0
投票

引用没有成员别名。与

中的问题相同
#include <array>
int main()
{
    using arr_t = std::array<int,42>&;
    using elem_broken = arr_t::value_type;          // error
    using elem_t = std::decay_t<arr_t>::value_type; // ok
}

您对 SFINAE 使用

std::decay_t
,但在查询成员别名时却错过了使用它。

template <typename T>
std::enable_if_t<is_array<std::decay_t<T>>::value>
do_something_prob(T&& arr, typename std::decay_t<T>::value_type mul); 

完整演示

© www.soinside.com 2019 - 2024. All rights reserved.