从第一类型的第二个非类型参数中推导出第一类型

时间:2018-04-03 10:27:25

标签: c++ templates c++17 type-deduction

我有以下功能:

/// <summary>
/// Check whether next character in std::basic_istream is what expected. Skip it if so; otherwise, set fail flag.
/// </summary>
template <typename TCharType, TCharType char_>
std::basic_istream<TCharType>& skipIf(std::basic_istream<TCharType>& istream_)
{
    if ((istream_ >> std::ws).peek() == char_) {
        istream_.ignore();
    }
    else {
        istream_.setstate(std::ios_base::failbit);
    }
    return istream_;
}

它的工作原理如下:

std::istringstream is {"some ; string"};
std::string temp;
if(is >> temp >> skipIf<char, ';'> >> temp) {
    // blah blah
}

是否可以从给定的TCharType模板参数中推断char_?如果我能写出

那就太好了
  • skipIf<';'> - &gt;推导为char
  • skipIf<L';'> - &gt;推导为wchar_t
  • skipIf<u';'> - &gt;推导为char16_t
  • skipIf<U';'> - &gt;推导为char32_t

2 个答案:

答案 0 :(得分:4)

您可以使用C ++ 17的新auto非类型模板参数来实现。稍微重新排列:

template <auto char_, typename TCharType = decltype(char_)>
std::basic_istream<TCharType>& skipIf(std::basic_istream<TCharType>& istream_)
{
    if ((istream_ >> std::ws).peek() == char_) {
        istream_.ignore();
    }
    else {
        istream_.setstate(std::ios_base::failbit);
    }
    return istream_;
}

你应该得到你所追求的,确切地说。您可以通过添加更多检查(作为static_assert或SFINAE)来改进它,以确保TCharType确实是标准或扩展字符类型之一,但这是食谱解决方案。

答案 1 :(得分:1)

我会放一个rows来使它好像第二个参数从未存在过。