在现代C++中是否可以将字符串文本作为参数传递给C++模板?
Is it possible in modern C++ to pass a string literal as a parameter to a C++ template?
是否可以在"现代C++"(C++17 或更高版本(中将字符串文本作为参数传递给C++模板?
我意识到你可以用构造函数参数来做到这一点;我只是认为将其作为模板参数会更方便,而不是深埋在 cpp 文件中。我很好奇这是否是现代C++的新功能。请参阅下面的伪代码,了解我正在尝试执行的操作:
伪代码示例:
// Header File /////////////////////////
template<constexpr string Name>
class ModuleBase {
public:
ModuleBase();
string name;
};
class xyz : ModuleBase<"xyz"> {
public:
xyz();
};
// Cpp File //////////////////////////
template<string_literal Name>
ModuleBase<Name>::ModuleBase() {
name = Name;
}
xyz::xyz() : ModuleBase() {
}
是的,在 c++20 中。
问题是确定模板非类型参数的唯一性很困难。
C++20增加了<=>
宇宙飞船操作员比较。 如果它是非用户提供的(并且仅基于非用户提供的<=>
依次递归重复((以及其他一些要求;请参阅 p0732(,则该类型可以用作非类型模板参数。
此类类型可以从constexpr
构造函数中的原始"strings"
构造,包括使用 c++17 演绎指南使它们自动调整大小。
由于存储的数据的大小可能是类型的一部分,因此您需要将该类型作为auto
类型化非类型参数或其他自动推断的类型。
请注意,将模板的实现放在 cpp 文件中通常是一个坏主意。 但这是另一个问题。
在你得到 c++20 并且如果你有 boost,你可能会发现以下宏很有用:
#define C_STR(str_) boost::mpl::c_str< BOOST_METAPARSE_STRING(str_) >::value
然后按如下方式使用:
template<const char* str>
structe testit{
};
testit<C_STR("hello")> ti;
这比直接传递字符串文字更丑陋,但在 C++20 中,也可以使用 NTTP constexpr lambda 返回字符串:
#include <string_view>
template<auto getStrLambda>
struct MyType {
static constexpr std::string_view myString{getStrLambda()};
};
int main() {
using TypeWithString = MyType<[]{return "Hello world!";}>;
return 0;
}
此处的编译器资源管理器示例。
它可以在 C++17 中完成,但在将 C 字符串作为名称传递之前,您需要static constexpr
#include<cstddef>
#include<string> //std::size()
namespace util {
template<std::size_t N>
using c_str = char const [N];
template<auto const & str, std::size_t iter = std::size(str), char const ... chars>
struct c_str_to_arg_pack {
using arg_pack_t =
typename c_str_to_arg_pack<str, iter-1, str[iter-1], chars ... >
::arg_pack_t;
};
template<auto const & str, char const ... chars>
struct c_str_to_arg_pack<str, 0, chars ...> {
using arg_pack_t = c_str_to_arg_pack<str, 0, chars...>;
template <template <char ...> typename T>
using apply = T<chars ...>;
};
template<auto const & str, char const ... chars>
using c_str_to_arg_pack_t = typename c_str_to_arg_pack<str, chars ... >::arg_pack_t;
}//end util
#include<string_view>
#include<array>
template <char ... chars>
struct module_base {
std::string const & get_name() {
static std::string name = []()
{
std::string name;
name.reserve(sizeof...(chars));
(name += ... += chars);
return name;
}();
return name;
};
static constexpr std::array<char, sizeof ... (chars)> name_backing {chars ...};
static constexpr std::string_view constexpr_name {name_backing.begin(), name_backing.size() };
static int instance_count;
module_base (){
++instance_count;
}
virtual ~module_base() = default;
};
template <char ... chars>
int module_base<chars ...>::instance_count {};
template <auto const & name>
struct xyz : util::c_str_to_arg_pack_t<name>::template apply<module_base> //edit, formerly missing 'template'
{};
template <auto const & name>
struct abc : util::c_str_to_arg_pack_t<name>::template apply<module_base> //edit, formerly missing 'template'
{};
#include<iostream>
int main(){
static constexpr util::c_str<std::size("beansn")> beans {"beansn"};
xyz<beans> test{};
std::cout << test.get_name();
static constexpr util::c_str<std::size("beansn")> beans_two {"beansn"};
abc<beans_two> test_two{};
std::cout << test_two.constexpr_name;
std::cout << decltype(test)::instance_count << 'n';
std::cout << decltype(test_two)::instance_count << 'n';
}
相关文章:
- 文本文件中的单词链表
- 从命令行c++发送文本文件名
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 2D数组来自文本输入,中间有空格
- 如何将内容数组写入文本文件?
- 无法通过空白将文本文件行分隔为矢量
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- C++将文本文件中的数据读取到结构数组中
- 在指针的帮助下,文本文件中单词的频率
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- 将值从二维数组输出到文本文件
- 如何在c++中从文本文件中逐行读取整数
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 从文本文件中读取时钟时间和事件时间并进行处理
- 如何从文本文件中读取值和数组
- 如何在C++中确定文本文件中的元素是字符还是数字
- 如何根据单词在文本中出现的概率输出单词
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- C++试图读取一个文件并输出到另一个文本文件
- 如何通过套接字将文本文件的内容从服务器发送到客户端