字符串文字取决于模板类型参数?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符串文字取决于模板类型参数?相关的知识,希望对你有一定的参考价值。

我有一个可以解析字符串(日期)的类。我希望能够解析普通字符串和宽字符串:

MyClass x;
x.parse("2018-02-27");
x.parse(L"2018-02-27");

由于解析普通字符串和宽字符串的代码基本相同,因此使用模板是有意义的:

template<typename CharT>
void parse(const CharT *str)
{
    // ...
}

现在,为了解析我将使用get_time函数。它需要fmt参数,它是const CharT *类型,我想为它提供一个字符串文字。它必须是普通或宽字符串文字,具体取决于模板类型参数:

template<typename CharT>
void parse(const CharT *str)
{
    tm date;
    basic_istringstream<CharT> date_stream{str};
    date_stream >> get_time(&date, ("%Y-%m-%d" or L"%Y-%m-%d", but how to choose??) );
    // ...
}

我只对两个模板实例化感兴趣:char和wchar_t。我试图使用非类型模板参数,但没有设法得到任何编译。

实现函数/模板最优雅的方法是什么?

答案

我第一次尝试在那里使用qakxswpoi并不顺利,但变量模板看起来很好:

if constexpr

为了记录,这是我第一次尝试的丑陋事情:

template <typename CharT>
constexpr CharT const *timeFmt;

template <>
constexpr auto timeFmt<char> = "%Y-%m-%d";

template <>
constexpr auto timeFmt<wchar_t> = L"%Y-%m-%d";

template <typename CharT>
void parse(const CharT *str)
{
    std::tm date;
    std::basic_istringstream<CharT> date_stream{str};
    date_stream >> std::get_time(&date, timeFmt<CharT>);
    // ...
}
另一答案

添加特质类:

template<typename CharT>
void parse(const CharT *str)
{
    std::tm date;
    std::basic_istringstream<CharT> date_stream{str};
    date_stream >> std::get_time(&date, []{
        if constexpr (std::is_same_v<CharT, wchar_t>)
            return L"%Y-%m-%d";
        else
            return "%Y-%m-%d";
    }());
    // ...
}

然后用作:

template <typename CharT>
struct format {
    static const CharT* const v;
};

template<> const char* const format<char>::v="%Y-%m-%d";
template<> const wchar_t* const format<wchar_t>::v=L"%Y-%m-%d";

如果你感觉雄心勃勃,你可以将实际的重复格式合并到date_stream >> get_time(&date, format<CharT>::v); (然后在必要时使用标记粘贴在前面粘贴#define) - 但实际上,我认为这是更多的机械而不是它的价值。

另一答案

除了变量模板和类模板,函数模板也可以:

L

然后,template<typename T> const T* get_format_str(); char的相应专业化:

wchar_t

template<> const char* get_format_str<char>() { return "%Y-%m-%d"; } template<> const wchar_t* get_format_str<wchar_t>() { return L"%Y-%m-%d"; } 函数模板中使用此函数模板:

parse()

这种方法的优点是:

  • 它只需要C ++ 98(对于需要C ++ 14的变量模板)。
  • 无法修改指向文字字符串的指针(只能修改函数返回的指针的副本)。

以上是关于字符串文字取决于模板类型参数?的主要内容,如果未能解决你的问题,请参考以下文章

如何定义具有重载的函数以恰好具有 1 或 2 个参数,这些参数的类型取决于使用的字符串文字

字符串文字不允许作为非类型模板参数

在“char 类型”模板化类中使用字符串文字

使用字符串文字作为 Django 模板中模板标签的参数

关于模板

xml Eclipse模板(代码片段)检查参数并最终抛出IllegalArgumentException