jeudi 18 juin 2020

Mixing templates with std::enable_if_t and specialisation

I've written some template code that is very reliant on std::enable_if_t - with many functions looking something like this

template<typename T, typename R>
std::enable_if_t<std::is_same<R, bool>::value, R> do_foo(T data)
{
    return true;
}

for a variety of std::is_* types.

However - headers are getting bloated and there are more than a few simple ones which could be simply specialised and declared as

// header
template<>
std::string do_foo(std::string bb)

// impl 
template<>
std::string do_foo(std::string bb)
{
    return "Booyah";
}

This of course doesn't work - as there is nothing to properly specialise from (as I understand it). Adding something like

template<typename T, typename R> 
R do_foo(T bb)
{
   static_assert(std::is_same<T, void>::value && false, "No use here");   
}

Results in errors like call of overloaded 'do_foo<std::string, std::string>(std::string)' is ambiguous - presumably a static assert only becomes evaluated once a template instantiation is chosen.

Can I have the best of both worlds here? Essentially I'd like for some templates to resolve to std::enable_if_t types via SFINAE, some to be specialised as to have definitions in impl files, and a default that is never used.

FWIW - my target C++ standard is C++11, but I'm guessing features from C++14/17 may make this possible, so they are good too. Please ignore the very likely chance of overlap/ambiguity between the specialisations and the SFINAE cases - well aware of that.

Aucun commentaire:

Enregistrer un commentaire