将字符串文字作为非类型参数传递给类模板
我想声明一个类模板,其中模板参数之一采用字符串文字,例如 my_class<"string">
。
谁能给我一些可编译的代码,它声明了一个简单的类模板,如上所述?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我想声明一个类模板,其中模板参数之一采用字符串文字,例如 my_class<"string">
。
谁能给我一些可编译的代码,它声明了一个简单的类模板,如上所述?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(17)
您可以有一个
const char*
非类型模板参数,并向其传递一个带有static
const char[]变量code> 链接,这与直接传递字符串文字相差不远。http://coliru.stacked-crooked.com/a/64cd254136dd0272
You can have a
const char*
non-type template parameter, and pass it aconst char[]
variable withstatic
linkage, which is not all that far from passing a string literal directly.http://coliru.stacked-crooked.com/a/64cd254136dd0272
进一步从尼尔的答案来看:根据需要将字符串与模板一起使用的一种方法是定义一个特征类并将字符串定义为该类型的特征。
印刷
Further from Neil's answer: one way to using strings with templates as you want is to define a traits class and define the string as a trait of the type.
prints
C++20
fixed_string
+“非类型模板参数中的类类型”显然,对此的提案首先被接受,但随后被删除:"字符串文字作为非类型模板参数"
删除是部分原因是因为它被认为很容易处理另一个被接受的提案:“非类型模板参数中的类类型”。
已接受的提案包含一个具有以下语法的示例:
我将尝试使用一个示例来更新此示例,一旦我看到支持它的编译器,该示例实际上会告诉我任何信息。
Redditor 还表明以下内容可以在 GCC master 上编译,前提是您定义了自己的
basic_fixed_string
版本,该版本尚未包含在标准库中:https: //godbolt.org/z/L0J2K2g++ -std=c++2a
9.2.1 无法编译该文件:参考书目:https://botondballo.wordpress.com/2018/03/28/trip -report-c-standards-meeting-in-jacksonville-march-2018/
这对于 C++17
if constexpr
来说尤其酷:C++编译时的if / else?这种功能似乎与 C++20 中令人敬畏的“constexpr everything”提案一致,例如: 是否可以在 constexpr 中使用 std::string ?
C++20
fixed_string
+ "Class Types in Non-Type Template Parameters"Apparently, a proposal for this was first accepted, but then removed: "String literals as non-type template parameters"
The removal was partly because it was deemed to be easy enough to do with another proposal that was accepted: "Class Types in Non-Type Template Parameters".
The accepted proposal contains an example with the following syntax:
I'll try to update this with an example that actually tells me anything once I see a compiler that supports it.
A Redditor has also shown that the following compiles on GCC master, provided you define your own version of
basic_fixed_string
which was not in the standard library yet: https://godbolt.org/z/L0J2K2g++ -std=c++2a
9.2.1 from the Ubuntu PPA fails to compile that with:Bibliography: https://botondballo.wordpress.com/2018/03/28/trip-report-c-standards-meeting-in-jacksonville-march-2018/
This will be especially cool with the C++17
if constexpr
: if / else at compile time in C++?This kind of feature appears to be in line with the awesome "constexpr everything" proposals that went into C++20, such as: Is it possible to use std::string in a constexpr?
抱歉,C++ 目前不支持使用字符串文字(或实际文字)作为模板参数。
但重新阅读你的问题,这就是你要问的吗?你不能说:
但你可以说
Sorry, C++ does not currently support the use of string literals (or real literals) as template parameters.
But re-reading your question, is that what you are asking? You cannot say:
but you can say
这是使用 MPLLIBS 将字符串作为模板参数传递的解决方案 (C++11)。
打印:
github 上的库: https://github.com/sabel83/mpllibs
This is a solution with MPLLIBS to pass a strings as template arguments ( C++11 ).
prints:
The lib on github: https://github.com/sabel83/mpllibs
尝试将函数的地址作为模板参数传递。
Try it with pasing the address of a function as the template argument.
编辑:好的,你的问题的标题似乎有误导性
看起来您正在尝试实现:
这适用于任何类型,对于第一个参数:
int
、float
、double
等等。现在,如果您确实想将第一个参数的类型限制为仅
int
、float
或double
;你可以想出一些更复杂的东西,比如如果你删除最后一行的注释,你将有效地得到一个编译器错误。
不允许使用字符串文字
C++2003 ISO/IEC 14882-2003 §14.1
ISO/IEC 14882-2003 §14.3.2:
看起来它在即将推出的 C++0X 中不会改变,请参阅当前草案 14.4.2 模板非类型参数。
EDIT: ok the title of your question seems to be misleading
It looks like you're trying to achieve:
This would work for any type, for the first parameter:
int
,float
,double
, whatever.Now if you really want to restrict the type of the first parameter to be only
int
,float
ordouble
; you can come up with something more elaborate likeIf you remove the comment on the last line, you'll effectively get a compiler error.
String literals are not allowed by C++2003
ISO/IEC 14882-2003 §14.1:
ISO/IEC 14882-2003 §14.3.2:
And it looks like it's not going to change in the upcoming C++0X, see the current draft 14.4.2 Template non-type arguments.
根据您在尼尔的回答下的评论,另一种可能性如下:
打印
Based on your comments under Niel's answer, another possibility is the following:
prints
您不能直接将字符串文字作为模板参数传递。
但您可以接近:
您所需要的只是此处的一个小头文件。
替代方案:
定义一个全局
char const *
并将其作为指针传递给模板。 (此处)缺点:需要模板参数列表之外的附加代码。如果您需要指定字符串文字“inline”,则它不适合。
使用非标准语言扩展。 (此处)
缺点:不保证适用于所有编译器。
使用
BOOST_METAPARSE_STRING
。 (此处)缺点:您的代码将依赖于 Boost 库。
使用 char 的可变参数模板参数包,例如
str_t<'T','e','s','t'>
。这就是上述解决方案在幕后为您所做的事情。
You cannot pass a string literal directly as a template parameter.
But you can get close:
All you need is a small header file from here.
Alternatives:
Define a global
char const *
and pass it to the template as pointer. (here)Drawback: Requires additional code outside of the template argument list. It is not suitable, if you need to specify the string literal "inline".
Use a non-standard language extension. (here)
Drawback: Not guaranteed to work with all compilers.
Use
BOOST_METAPARSE_STRING
. (here)Drawback: Your code will depend on the Boost library.
Use a variadic template parameter pack of char, e.g.
str_t<'T','e','s','t'>
.This is what the above solution does for you behind the scenes.
使用代理
static constexpr const char type_name_str[] = {"type name"};
将字符串作为模板参数传递。使用[]
定义字符串很重要。Use proxy
static constexpr const char type_name_str[] = {"type name"};
for passing string as template parameter. Defining string using[]
is important.我不确定,但这是您想要的吗?
I am not sure but is this something what you want?
也许不是OP所要求的,但如果你使用
boost
,你可以创建一个像这样的宏:然后使用如下:
Maybe not what the OP is asking, but if you use
boost
, you can create a macro like this for example:Then use as follows:
以上内容适用于我在 Windows 上使用
Clang 11
进行生产。(已编辑)我现在在 Windows 上的 clang 中完全这个使用:
The above is working for me in production using
Clang 11
on Windows.(edited) I now use exactly this in clang on Windows:
我一直在努力解决类似的问题,最后想出了一个简洁的实现,将字符串文字解压到
char...
模板参数包中,并且不使用 GNU 文字运算符模板扩展:一个主要警告:这取决于 C++20 功能(类值作为非类型模板参数;P0732,P1907),(截至 2020 年 12 月)仅(部分)在 GCC 9 及更高版本中实现(预处理器功能测试:
(__cpp_nontype_template_args >= 201911L) || (__GNUG__ > ;= 9)
)。然而,由于该功能是标准的,其他编译器赶上只是时间问题。I was struggling with a similar problem and finally came up with a concise implementation that unpacks the string literal into a
char...
template parameter pack and without using the GNU literal operator template extension:A major caveat: this depends on a C++20 feature (class values as non-type template arguments; P0732, P1907), which (as of December 2020) is only (partially) implemented in GCC 9 and later (preprocessor feature test:
(__cpp_nontype_template_args >= 201911L) || (__GNUG__ >= 9)
). However, since the feature is standard, it is only a matter of time before other compilers catch up.这是一个解决方案和扩展/示例
我的解决方案扩展了 https://ctrpeach。 io/posts/cpp20-string-literal-template-parameters/
here is a solution and extensions/examples
my solution extends https://ctrpeach.io/posts/cpp20-string-literal-template-parameters/
我没有看到提到的另一个 C++20 解决方案,但它足够简单并且适合我自己的需求,是使用 constexpr lambda 作为返回字符串的 NTTP:
编译器资源管理器示例 这里。
Another C++20 solution I don't see mentioned, but which was sufficiently simple and suitable for my own needs, is to use a constexpr lambda as the NTTP returning the string:
Compiler explorer example here.
实际上,具有 n 个可见字符的字符串文字是 const char[n+1] 类型。
Actually, string literals with n visible characters are of type
const char[n+1]
.