简体   繁体   English

const 指针的模板参数推导失败

[英]Template argument deduction failing for const pointers

I don't understand why template argument deduction fails in this case:我不明白为什么在这种情况下模板参数推导失败:

template<class Iterator> void
f(Iterator x, const Iterator y) {}

int main()
{
    const int* cpi;
    int* pi;
    f(pi,cpi);
}

Why does Iterator does not deduce to int* for the second parameter?为什么Iterator不会为第二个参数推导出int*

What would be the most idiomatic declaration for f ? f最惯用的声明是什么?

The Iterator can be either int * or const int * . Iterator 可以是int *const int * The qualifier const of the second function parameter means either int * const or const int * const .第二个函数参数的限定符 const 表示int * constconst int * const

You could create a trait to check if the iterator is an iterator over const values.您可以创建一个特征来检查迭代器是否是 const 值上的迭代器。

#include <iterator>    // iterator_traits
#include <type_traits> // is_const_v, remove_pointer_t, enable_if_t

template<typename T>
struct is_const_iterator {
    // Define a pointer type to the type iterated over. Something already a pointer
    // will still be a pointer
    using pointer = typename std::iterator_traits<T>::pointer;

    // Remove the pointer part from the type and check for constness.
    static const bool value = std::is_const_v<std::remove_pointer_t<pointer>>;
};

// Helper variable template to simplify the use of the above.
template<class T>
inline constexpr bool is_const_iterator_v = is_const_iterator<T>::value;

SFINAE use of is_const_iterator_v SFINAE 使用is_const_iterator_v

template<class It, class CIt, std::enable_if_t<is_const_iterator_v<CIt>, int> = 0>
void f(It x, CIt y) {
    //for(; x != y; ++x) std::cout << *x << '\n';
}

Alternatively, if your function doesn't have other overloads (does not need SFINAE), you can use static_assert to make it even clearer for the user:或者,如果您的函数没有其他重载(不需要 SFINAE),您可以使用static_assert使用户更清楚:

template<class It, class CIt>
void f(It x, CIt y) {
    static_assert(is_const_iterator_v<CIt>, "Arg 2 must be a const iterator");
    //for(; x != y; ++x) std::cout << *x << '\n';
}

Example:例子:

#include <iostream>
#include <vector>

int main() {
    int values[]{1, 2};

    int* pi = values;
    const int* cpi = values + std::size(values);

    std::vector<int> v{3, 4};

    f(pi, cpi);
    f(v.begin(), v.cend());
    // f(pi, pi);             // error, pi is non-const
    // f(v.begin(), v.end()); // error v.end() is non-const
}

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

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