c++ - 转发引用的参数类型检查不起作用

标签 c++ templates forwarding-reference

我正在尝试编写一个仅接受 std::vector 作为参数的模板函数。但是,我提出的方法仅适用于普通参数或左值参数,不适用于转发引用参数。

以下代码无法编译。

template <typename T, typename = typename std::enable_if< std::is_same<T, std::vector< typename T::value_type, typename T::allocator_type > >::value>::type >
int f(T && a) {
    return a.size();
}

int main() {
    std::vector<int> a;
    f(a);
}

但是,如果我将 f 的参数类型替换为左值引用或按值类型传递,如下所示:

template <typename T, typename = typename std::enable_if< std::is_same<T, std::vector< typename T::value_type, typename T::allocator_type > >::value>::type >
int f(T a) {
    return a.size();
}

比它编译。<​​/p>

请注意,我需要有一个转发引用的参数。

我错过了什么?

最佳答案

如果您只想接受 vector ,那么您的代码可以简化很多。您可以指定一个带有任何类型参数的 std::vector ,而不是使用 SFINAE 。这看起来像

template <typename... Pack>
int f(std::vector<Pack...>const & a)
{
    return a.size();
}

您的 SFINAE 方法不起作用的原因是,当您将左值传递给函数时,T 被推导为引用类型。当涉及到诸如

之类的事情时,引用类型的工作方式与类型本身不同
typename T::value_type

要解决此问题,您需要使用 std::remove_reference 删除 T 的引用。这会给你一个类似的函数

template <typename T, typename VecType = typename std::remove_reference<T>::type, typename = typename std::enable_if< std::is_same<VecType, std::vector< typename VecType::value_type, typename VecType::allocator_type > >::value>::type >
int f(T && a) {
    return a.size();
}

关于c++ - 转发引用的参数类型检查不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58806120/

相关文章:

C++通用引用和LRef参数的类型推导

c++ - 创建多个txt文件以在c++中存储数据

c++ - Solaris CC 要求的 template<> 语法,但被 MSVC 和 GCC 禁止

c++ - 如何将类型约束和隐式转换与 C++11 通用引用相结合?

c++ - 当函数不存在时 SFINAE 回退

c++ - 如何使用模板将 lambda 转换为 std::function

c++ - 条件类型特征通用引用的问题

c++ - 在C++和kinect中获取特定的关节位置

c++ - 为什么要将 operator< 定义为非成员?

c++ - 如何使用 OpenGL、SDL 和 C++ 绘制文本?