C++ std::源位置作为非类型模板参数
在我无限期地探索可以用作非类型模板参数的限制时,我试图看看是否可以将C++ std::源位置作为非类型模板参数,c++,c++20,std-source-location,C++,C++20,Std Source Location,在我无限期地探索可以用作非类型模板参数的限制时,我试图看看是否可以将std::source\u location用作非类型模板参数。 由于一条奇怪的消息而失败,因为我认为源位置是某种神奇的结构 非类型模板的类型“std::experimental::source_location” 参数不是结构类型 它失败了,所以我尝试使用.file_name来解决这个问题,但也失败了() 注意:已忽略候选模板:替换失败:指向 模板参数中不允许字符串文字的子对象 #包括 #包括 模板 void log_firs
std::source\u location
用作非类型模板参数。
由于一条奇怪的消息而失败,因为我认为源位置是某种神奇的结构
非类型模板的类型“std::experimental::source_location”
参数不是结构类型
它失败了,所以我尝试使用.file_name来解决这个问题,但也失败了()
注意:已忽略候选模板:替换失败:指向
模板参数中不允许字符串文字的子对象
#包括
#包括
模板
void log_first(){
静态布尔虚拟=([]{
标准::cout指定为:
struct源位置{
// ...
私人:
uint_least32_t line_u;//仅限展示
uint\u least32\u t列///仅用于说明
const char*文件名///仅限公开
const char*函数\u name;//仅用于说明
};
可以用作非模板参数的类型类型的规则要求类型是结构化的,这意味着,从emphasis mine开始:
结构类型是以下类型之一:
- 标量类型,或
- 左值引用类型,或
- 具有以下属性的文字类类型:
- 所有基类和非静态数据成员都是公共的且不可变且
- 所有基类和非静态数据成员的类型都是结构类型或其(可能是多维)数组
source\u location
的所有非静态数据成员都不是公共的,因此它不是结构化的,因此不能用作非类型模板参数
本部分:
模板:
对于引用或指针类型的非类型模板参数,或者对于类类型的非类型模板参数或其子对象中的引用或指针类型的每个非静态数据成员,引用或指针值不应引用或是(分别)的地址:
- [……]
- 字符串文字对象([lex.string])
但是,您可以创建自己的类型,即结构化类型,它可以从源位置构建。只是字符串不能是字符常量*
,它们必须拥有数据。如果您查看中的示例,我们可以构建:
模板
结构基本固定字符串{…};
模板结构A{};
使用T=A;
在这种情况下,这可能很难处理,因此您也可以选择一些合理的最大大小并继续使用。这是模板的无效参数。请注意,const char*
不能是模板参数,这是由于。删除auto
可以清楚地表明@MarekRchar const*
可以是模板参数ument,即使在C++03中也是如此。只是模板参数不能指向字符串文字,而file_name()
的来源可以是字符串文字。您知道为什么constepr const char*file_name()吗也不允许使用const noexcept;?可能是因为父对象不支持constexpr,或者我得到的指针指向的成员不支持constexpr,或者…OP正在尝试使用。file_name()
作为对象,而不是直接的源位置,所以你在引用中强调的部分不是真正正确的部分。@holt我两个都试过了…@nosenseal对,引用都适用,只是强调的部分。Barry我没有真正得到你的最后部分答案,你的意思是这样的吗?这有问题吗对于这个用例,似乎source_location::current被破坏了,因为我得到的是模板函数的位置,而不是调用者(我想是因为“调用”current是在编译时完成的)。你知道这是设计造成的还是一个不幸的限制?
#include<iostream>
#include<experimental/source_location>
template<auto src_loc = std::experimental::source_location::current().file_name()>
void log_first(){
static bool dummy =([]{
std::cout << "Logging first call" + src_loc << std::endl;
}(), false);
}
int main() {
log_first();
log_first();
}