类型推导/替换失败
Type deduction/substitution failure
考虑以下示例。
#include <string>
template<class CharT, class Traits = std::char_traits<CharT >, class Allocator = std::allocator<CharT >>
void f(const std::basic_string<CharT, Traits, Allocator>& s) {
}
int main() {
f("Hello World!");
}
编译时,我得到
不匹配的类型
‘const std::basic_string<_CharT, _Traits, _Alloc>’ and ‘const char []’
为什么编译器不能扣除"CharT"并转换为适当的basic_string<>
?我希望只有一个f()的签名对任何存在到basic_string<>
转换的参数类型有效,有解决这个问题的方法吗?
您正在向函数传递一个原始字符串,它不是std::string
,而是一个字符数组,一个const char []
即使std::string
有一个获取char数组的构造函数,在模板论证推导过程中也不会应用隐式类型转换(这正是您遇到的问题)。有关该主题的更多信息,请参阅此线程。
有两种可能的解决方案:
-
将
std::string
而不是原始字符串传递给函数:f( std::string( "hello" ) );
-
编写一个使用原始字符串的函数重载:
template<typename CHAR_T , std::size_t LENGHT> void f( const CHAR_T (&string)[LENGTH] ) { f( std::string( string ) ); //Just wrap the call to not duplicate code. }
您所要求的是编译器对每个basic_string<T>
进行迭代,直到确定正好有一个T
匹配为止。或者,它可以颠倒可能的图灵完整过程,找出template
参数是什么。template
参数的推导就是模式匹配:它获取参数,并将其与您的模式匹配,然后简单地推导类型。如果您想要更多,您需要告诉它如何反转从CharT
到basic_string<CharT,A>
构造函数的映射。C++1y使概念更简单,但你想要的那种机器仍然不存在。
到目前为止,最简单的解决方案是为char
和wchar_t
basic_string
s(实际函数,而不是template
s)设置两个重载,然后让它们调用一个template
泛型函数,就像您在CharT
中明确传递的那样。
Fancier将涉及实际执行上述反转的代码,其中您可能让它从一组可接受的字符串中工作,并检查可以从哪些参数中构造参数,断言只有一个选项,并以这种方式推导CharT
。虽然有趣,但我怀疑这是否值得。
这样就可以了。
您正在为您的函数指定一个char数组,witch应该得到std::string。您需要使用构造函数来转换这些。
#include <string>
template<class CharT, class Traits = std::char_traits<CharT >, class Allocator = std::allocator<CharT >>
void f(const std::basic_string<CharT, Traits, Allocator>& s) {
}
int main() {
std::string str("Hello World!");
f(str);
}
- 模板参数替换失败,并且未完成隐式转换
- 要求子句中不允许哪些替换失败?
- 模板参数推导/替换失败,lambda作为函数指针
- 类模板参数推导失败会导致替换失败
- C++ 带有 decltype 的 SFINAE:替换失败成为错误?
- 折叠表达式模板参数推导/替换失败
- 使用"std::function"和先前推断的模板参数替换失败 - 为什么?
- 模板参数推导/替换失败 C++
- 当Boost ::绑定模板函数时,模板参数扣除/替换失败
- SFINAE使用演绎,但用替换失败
- 为什么代码中的模板参数推导/替换失败?-.
- GCC 模板参数推断/替换失败
- 为什么模板参数推导/替换失败
- 模板模板参数的替换失败
- C++模板参数推导/替换失败
- C++模板参数推导/替换失败:
- 使用类型名参数时,模板参数推导/替换失败
- 有没有办法将模板的替换失败转换为布尔值(真/假)或标签(标准::true_type/标准::false_type)
- 模板参数扣除/替换失败-STD :: find()
- std::tuple_cat替换失败