如何使用 enable_if 来根据迭代器迭代的类型启用模板函数?

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

我目前有一个看起来像这样的功能:

    template<typename input_iterator>
    std::string doit(input_iterator beg, input_iterator end)
    {
        static_assert(sizeof(*beg) == 1, "Size one only, please");
        return do_something(beg, end);
    }

这很好用

std::vector<uint8_t> v1 {1, 2, 3};
doit(v1.begin(), v1.end());

成功而

std::vector<int> v2 {1, 2, 3};
doit(v2.begin(), v2.end());

static_assert
失败。

我更喜欢让代码在调用站点而不是在被调用函数中失败,并摆脱

static_assert
.

我尝试了很多东西,包括

enable_if
的变体,但我没有找到正确的组合。我最近的尝试是

    template<typename input_iterator, 
       std::enable_if<sizeof(std::iterator_traits<input_iterator>::value_type) == 1>>
    std::string doit(input_iterator beg, input_iterator end)
    {
        return do_something(beg, end);
    }

但是无论我的迭代器是什么类型,这都会导致函数不匹配失败。

有人可以指出我正确的方向吗?我不是在寻找概念,我需要使用 C++17 编译的代码。

谢谢。

c++ c++17 sfinae
1个回答
0
投票

这似乎可以解决问题:

https://godbolt.org/z/6GjcoYrzG

#include <string>
#include <vector>
#include <stdexcept>
#include <type_traits>

template<typename input_iterator>
auto doit(input_iterator beg, input_iterator end)
 -> std::enable_if_t<sizeof(*beg) == 1, std::string>
{
    throw std::runtime_error("");
    // return do_something(beg, end);
}

int main() {
    std::vector<uint8_t> v1 {1, 2, 3};
    doit(v1.begin(), v1.end());

    std::vector<int> v2 {1, 2, 3};
    doit(v2.begin(), v2.end());  // error: no matching function for call to 'doit'

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.