按照standard, 14.8.2.1从函数调用中推导模板参数[temp.deduct.call]其中P
是模板参数,A
是该位置中的函数调用参数:
2 If P is not a reference type:
If A is an array type, the pointer type produced by the array-to-pointer = standard conversion ([conv.array]) is used in place of A for type deduction; otherwise,
If A is a function type, the pointer type produced by the function-to-pointer standard conversion ([conv.func]) is used in place of A for type deduction; otherwise,
If A is a cv-qualified type, the top-level cv-qualifiers of A's type are ignored for type deduction.
If P is a cv-qualified type, the top-level cv-qualifiers of P's type are ignored for type deduction. If P is a reference type, the type referred to by P is used for type deduction. [...]
因此,考虑
std::string s{"hello"};
const std::string& sr{s};
Literal l(sr);
A
(SR)是const std::string&
但常量性不考虑,所以编译器认为std::string
。这匹配你的
template <typename V>
Literal(V val)
{
value = val;
}
所以它使用这种专业化。如果你有专门的
template<>
Literal(std::string val)
编译器会发现这种专业化,这可能是你将不得不做的,并使用移动语义。
#include <iostream>
#include <string>
struct S {
template<typename T>
S(T t) { std::cout << "T t\n"; }
std::string value_;
};
template<>
S::S(std::string value) {
std::cout << "string\n";
value_ = std::move(value);
}
template<>
S::S(const std::string&) {
std::cout << "const string&\n";
}
int main() {
S s1(42);
std::string foo{"bar"};
const std::string& foor = foo;
S s2(foo);
S s3(foor);
}
http://ideone.com/eJJ5Ch
你没有申报'value'。这是你会得到的错误:_main.cpp:12:9:错误:'value'未在此范围内声明 value = val; _ –
@HenriqueBarcelos ATL :: CComVariant value'在'Expression'中声明。为了简洁,我只发布了相关的模板内容。 –
我假设'value'是在基类中定义的。 – Bathsheba