2012-06-04 28 views
10

在C++中新的用户定义的字面概念提出字符串常量的一些非常有趣的用途,如:基于字符串的用户定义文字是否可以强类型化?

"Goodbye %s world"_fmt("cruel"); 
"Goodbye %s world"_fmt(123); // Error: arg 1 must be convertible to const char* 

R"(point = \((\d+), (\d+)\))"_re; // Builds DFA at compile-time. 

typedef table< 
    column<"CustId"_name , std::string>, 
    column<"FirstName"_name, std::string>, 
    column<"LastName"_name , std::string>, 
    column<"DOB"_name  , date  > 
> Customer; 

然而,当我建立这些种GCC结构,例如:

template <char... Chars> Name<Chars...> operator "" _name() { 
    return Name<Chars...>(); 
} 

auto a = 123_name; // OK 
auto b = "abc"_name; // Error 

我得到以下错误:

…unable to find string literal operator ‘operator"" _name’ with ‘const char [4]’, ‘long unsigned int’ arguments 

从读书的时候,我猜的可变参数模板形式并不适用于包括UDL派生d来自字符串文字。

  1. 实际上是不是使用可变参数模板形式解决字符串文字的情况?
  2. 如果是这样,有没有人有任何洞察到为什么这样一种有用的UDL形式被排除在标准之外?
+0

对于为每一个文字创建一个新类型,这些类型完全不同于另一个文字有什么用处? –

+0

@NicolBolas:在示例中,您*希望*不同的文字具有不同的类型。此外,文字的最终类型不一定是其字符的简单连接。例如,'freq:%g Hz'world'_fmt(44000)'可能会通过元编程的方式解析为类似Formatter (“freq:”,“Hz”)(44000)“。 –

+0

这也意味着你*不能传递它不是数字的东西,所以你不能传递它可能使用'operator <<'转换成流的东西,从而消除了定制数据类型的可能性。 –

回答

8

你说得对。字符串文字不能与可变参数模板形式(§2.14.8/ 5)使用:

If L is a user-defined-string-literal, let str be the literal without its ud-suffix and let len be the number of code units in str (i.e., its length excluding the terminating null character). The literal L is treated as a call of the form

operator "" X (str, len) 

我已经通过的建议文件(最近的我能找到的N2750)洗牌,找不到一个解释不允许使用可变模板形式。

+0

这可能是微不足道的两个功能的共同发展阻止了另一个使用另一个? –

+0

@Matthieu M.我不这么认为。我无法找到他们正在单独开发的证据(他们总是在同一篇论文中)。说实话,当我看到可变形式时,首先想到的就是OP在答案中展示的那种想法。我想假设委员会在这方面看到了一些潜在的问题。无论是这个还是一个非常烦人的疏忽。 –

+3

所有允许使用可变形式的用户定义文字都限于基本源字符集(仅仅因为语法不允许其他内容或浮点数)。字符串文字没有这个限制,所以对于多字节源文件/执行编码,你可以在字符串文字中使用c-chars,而这些c-chars可能不能表示为单个字符。这可能与决定不允许使用字符串文字的可变形式有关。 – bames53

2

允许这个的N3599已经在gcc和clang中实现了。

template<class CharT, CharT... chars> 
int operator ""_suffix(){ 
    return 42; 
} 
相关问题