问题:
在下面的代码中,模板参数类型推导似乎对第一个样本失败,但对第二个样本失败。我不明白为什么第一个样本无法推断T = char
。我认为从T
转换为"foo"
时可以推断出std::bacis_string<T>
,但即使这不起作用,我提供了第二个函数参数,我认为,显然会将T
限制为char
。 为什么会失败?
#include <iostream>
#include <string>
template <typename T>
void print(const std::basic_string<T>& a, const std::basic_string<T>& b)
{
std::cout << a << b << std::endl;
}
int main()
{
std::string bar = "bar";
print("foo", bar);
}
错误:
string.cpp:14:5: error: no matching function for call to 'print'
print("foo", bar);
^~~~~
string.cpp:6:6: note: candidate template ignored: could not match
'basic_string<type-parameter-0-0, char_traits<type-parameter-0-0>,
allocator<type-parameter-0-0> >' against 'char const[4]'
void print(const std::basic_string<T>& a, const std::basic_string<T>& b)
^
1 error generated.
#include <iostream>
#include <string>
template <typename T>
void print(const std::basic_string<T>& a, const std::basic_string<T>& b)
{
std::cout << a << b << std::endl;
}
int main()
{
std::string foo = "foo";
std::string bar = "bar";
print(foo, bar);
}
答案 0 :(得分:4)
问题是这里需要转换。要推导T
,编译器必须检查std::basic_string
的所有可能实例化,并查看哪些实例可以从const char*
(或实际const char (&)[4]
)构建。这当然是不可能的,因为它们中有无数的。它必须检查所有并且不能仅扫描构建者的const char*
或const char(&)[4]
的主要模板定义的原因是,对于某些T
,std::basic_string<T>
可能部分或完全专业化,这些专业化的成员与主要模板的成员没有任何关系。
答案 1 :(得分:1)
这是答案的简短版本。
编译器已char const[]
,并希望将其转换为std::basic_string<T>
。它如何解决T
的问题? 您知道您要匹配T = char
,但编译器不知道。
例如,它可以查找构造函数basic_string<T>(char const *)
。即使存在,它仍然没有说明T
应该是什么。
编译器不会迭代它知道的所有可能的类型名称,并为每个类型名称尝试basic_string<T>
,然后查看是否存在匹配的构造函数。
类似的例子:
template<typename T>
struct Foo
{
Foo(T t) {}
};
int main()
{
Foo(0); // error, can't deduce Foo<int>
}