#include <concepts>
#include <format>
#include <string_view>
#include <type_traits>
template <typename ... Args>
struct FmtString {
std::format_string<Args ...> text;
template <typename StringCompatible>
requires (std::convertible_to<StringCompatible, std::string_view>)
consteval FmtString(StringCompatible const& description)
: text(description)
{}
};
template <typename ... Args>
void fails(FmtString<Args ...> const&, Args&& ...) noexcept {}
template <typename... Args>
using FmtStringArgIdentity = FmtString<std::type_identity_t<Args> ...>;
template <typename ... Args>
void works(FmtStringArgIdentity<Args ...> const&, Args&& ...) noexcept {}
int main() {
works("test {}", 42);
fails("test {}", 42);
}
GCC 错误消息:
<source>: In function 'int main()':
<source>:28:10: error: no matching function for call to 'fails(const char [8], int)'
28 | fails("test {}", 42);
| ~~~~~^~~~~~~~~~~~~~~
<source>:18:6: note: candidate: 'template<class ... Args> void fails(const FmtString<Args ...>&, Args&& ...)'
18 | void fails(FmtString<Args ...> const&, Args&& ...) noexcept {}
| ^~~~~
<source>:18:6: note: template argument deduction/substitution failed:
<source>:28:10: note: mismatched types 'const FmtString<Args ...>' and 'const char [8]'
28 | fails("test {}", 42);
| ~~~~~^~~~~~~~~~~~~~~
Compiler returned: 1
查看libfmt的源码我能够使我的代码工作。不幸的是,我不明白为什么这样做有效,也不明白为什么模板参数推导失败。
fails
调用有什么问题,为什么 works
调用可以解决这个问题?
最佳答案
这是一个具有相同效果的更简单的示例:
#include <type_traits>
template <typename T>
struct foo {
template <typename U>
foo(U u) {}
};
template <typename T>
void fails(foo<T>,T) {}
template <typename T>
void works(std::type_identity_t<foo<T>>,T) {}
int main()
{
fails(12.0,42); // error
works(12.0,42);
}
你无法推断int
来自12.0
将用于转换为 foo<int>
。 double
之间根本没有关系。用作构造函数的模板参数和 int
用于实例化foo<int>
。任意foo<T>
有一个来自 double
的转换构造函数至foo<T>
.
std::type_identity
是一个非推导的上下文。对于 works<T>
,T
仅从 42
推导出来,和works<int>
实例化得到works<int>(foo<int>,int)
。直到现在隐式转换才开始,并且 12.0
可以转换为foo<int>
通过转换构造函数。
关于c++ - 为什么我需要 `std::type_identity_t` 来启用隐式类型转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77529748/