我正在尝试为std::string
参数创建一个专门的构造函数,但是当我用字符串参数调用它时,总是使用另一个。
struct Literal : Expression
{
template <typename V>
Literal(V val)
{
value = val;
}
};
template <>
Literal::Literal(std::string const& val)
{
value = val.c_str();
}
如果两者都在类中定义,无论是在类外部还是在发布的示例中都没有定义,那么只在类外部定义特化:当使用std::string
调用时,赋值{{1给出编译器错误。
如何正确专门化value = val
的构造函数模板?
答案 0 :(得分:6)
你没有。
您应该重载构造函数:Literal(const std::string&)
,您可以在struct
声明中执行此操作。
编译器总是尝试在模板之前匹配非模板重载。
答案 1 :(得分:4)
根据函数调用[temp.deduct.call]中的standard, 14.8.2.1 Deducing模板参数,其中 '1. Imput BomName
Dim BomName As String
BomName = InputBox("Enter BOM to check")
If BomName = "" Then
Exit Sub
Else
'continue program
End If
'2 Open BomName File & Vantage Parts File
Workbooks.Open (BomName)
Workbooks.Open ("Part Last Cost Demand wMin Qty.xlsx")
是模板参数,P
是该位置的函数调用参数:
2如果P不是参考类型:
如果A是数组类型,则使用由数组到指针=标准转换([conv.array])生成的指针类型代替A来进行类型推导;否则,
如果A是函数类型,则使用函数到指针标准转换([conv.func])生成的指针类型代替A进行类型推导;否则,
如果A是cv限定类型,则类型扣除将忽略A类型的顶级cv限定符。
如果P是cv限定类型,则类型推导将忽略P类型的顶级cv限定符。如果P是引用类型,则P引用的类型用于类型推导。 [...]
所以给出
A
std::string s{"hello"};
const std::string& sr{s};
Literal l(sr);
(sr)是A
但是不考虑常量,因此编译器考虑const std::string&
。这符合您的
std::string
所以它使用这种专业化。如果你有专门的
template <typename V>
Literal(V val)
{
value = val;
}
编译器会找到这个特化,这可能是你必须要做的并使用移动语义。
template<>
Literal(std::string val)
答案 2 :(得分:1)
很多时候,当重载是一种解决方案时,人们会尝试定义完全专业化。但过载可能是一个更好的解决方案。在您的情况下,我将使用string参数创建一个新的构造函数。 请记住,在重载解析中只考虑基本模板。以下文章是理解这个想法的一个很好的参考: http://www.gotw.ca/publications/mill17.htm
更新:
无论如何,为了改进我的答案,你可以尝试以下基本模板构造函数:
template <typename V>
Literal(V const& val)
{
value = val;
}