I currently have a function that looks like this:
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);
}
This works fine in that
std::vector<uint8_t> v1 {1, 2, 3};
doit(v1.begin(), v1.end());
succeeds while
std::vector<int> v2 {1, 2, 3};
doit(v2.begin(), v2.end());
fails at the static_assert
.
What I would prefer is to have the code fail at the call site rather than within the called function, and get rid of the static_assert
.
I have tried a number of things including variations on enable_if
but I haven't hit on the right combination. My latest attempt was
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);
}
but this resulted in no-matching-function failures no matter what type my iterators are.
Can someone please point me in the right direction? I'm not looking for concepts, I need code that will compile using C++17.
Thanks.
This seems to do the trick:
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;
}