c++ - 由于字符数组到指针衰减而无法推导非类型模板参数?

标签 c++ c++20 variadic-templates template-argument-deduction non-type-template-parameter

给出以下代码:

#include <algorithm>
#include <cstddef>
#include <iterator>
#include <source_location>

template<std::size_t N>
struct StringWrapper {
    // consteval to force only compile-time strings
    consteval StringWrapper(const char (&format_string)[N], std::source_location source_location = std::source_location::current())
        : SourceInfo{ source_location } {
        std::copy(std::begin(format_string), std::end(format_string), std::begin(FormatString));
    }

    char FormatString[N]{};

    // This here to motivate not using StringWrapper as non-type template argument
    std::source_location SourceInfo{};
};

// class-template-argument-deduction is not necessary here, see the first case in main

// variadic template, thus putting std::source_location at the end is not an option
template<std::size_t N, class... Args>
void log(StringWrapper<N> format_string, Args&&... args);

int main()
{
    log(StringWrapper{ "This {}, explicitly instantiating, but deducing the parameter" }, "works");
    log("This {}, could not match 'StringWrapper<N>' against 'const char *'", "fails");
}

有什么可能的解决方法可以解决此问题而不需要对调用站点进行更改?

一种可能性是使用 std::string_view ,但是这不会让我访问 N作为执行 log 中的常量表达式因此对于我来说这不是一个选择。

另一种可能是直接取 const char (&)[N] ,但是我失去了 std::source_location这也不是一个选择。

我明白为什么重载解析会倾向于采用 const char* 的函数一个带有 const char (&)[N] 的函数,但是我不明白为什么“StringWrapper”甚至没有尝试与“const char (&)[N]”匹配。

最佳答案

您可以使用类模板参数推导来执行此操作(将 log 更改为对象构造函数而不是普通函数)

template<std::size_t N, class... Args>
struct log{
    log(StringWrapper<N> src, Args&&... args){}
};

template<std::size_t N, class... Args>
log(const char(&)[N],Args&&...) -> log<N,Args...>;

template<std::size_t N, class... Args>
log(StringWrapper<N>,Args&&...) -> log<N,Args...>;

关于c++ - 由于字符数组到指针衰减而无法推导非类型模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74164953/

相关文章:

c++ - 拦截windows打开的文件

c++ - 检测 CRT 初始化是否在注入(inject)进程中完成

c++ - 对 reverse_iterator 的 C++20 更改是什么破坏了这段代码?

具有用户类型的 C++20 模板 <auto> 导致 GCC 9 中的 T/const T 类型不匹配

c++ - 如何静态检查模板的类型 T 是否为 std::vector<U>,其中 U 为 float、double 或 integral

c++ - 我们如何同时使用汉明距离和坐标之间的距离来匹配特征?

c++ - 为什么 range::iota_view 的构造函数不将参数移动到成员变量?

c++ - std::enable_if 不能用于禁用此声明

c++ - 使用可变参数模板函数包装基于省略号的函数

c++ - 什么是 __builtin_operator_new 及其工作原理?