使用以下代码,如果我尝试将模板数组转换为std :: string,而不是使用预期的std :: string转换方法编译器,则会引发歧义解决问题(因为它尝试调用数组转换方法):
#include <iostream>
template<typename TemplateItem>
class TestA
{
public:
TemplateItem Array[10];
operator const TemplateItem *() const {return Array;}
operator const std::string() const;
};
template<>
TestA<char>::operator const std::string() const
{
std::string Temp("");
return Temp;
}
int main()
{
TestA<char> Test2;
std::string Temp("Empty");
Temp = Test2; //Ambiguity error. std::string or TemplateItem * ?
return 0;
}
我需要对代码进行哪些修改才能使代码正确且隐式地解析为std :: string转换函数?特别是给定const TemplateItem *将被视为以null结尾的数组(它不太可能)。
答案 0 :(得分:5)
首先,您有歧义的原因:您提供转化为char*
和转换为std::string const
,std::string
同时喜欢它们。
顺便说一句,在回答您的问题之前,const
中的operator std::string const
曾经是个好主意,例如斯科特迈耶斯,但现在是ungood:它阻止了有效的移动。
无论如何,重新提出问题,避免隐式转换。使这些转换明确。现在我回答了另一个SO问题,有人(我相信这个人在拖钓)评论说C ++ 98不支持explicit
类型转换运算符。从技术上讲,这是真的,但作为技术评论却非常愚蠢。因为您不需要使用explicit
关键字(由C ++ 11支持),实际上这不是明确转换的好方法。而只是 name 那些转换:使用命名成员函数,而不是转换运算符。
#include <iostream>
template<typename TemplateItem>
class TestA
{
public:
TemplateItem Array[10];
TemplateItem const* data() const { return Array; }
std::string str() const;
};
template<>
std::string TestA<char>::str() const
{
return "";
}
int main()
{
TestA<char> test2;
std::string temp( "Empty" );
temp = test2.str(); // OK.
temp = test2.data(); // Also OK.
}
干杯&amp;第h
答案 1 :(得分:0)
我想补充一下,在考虑之后,这是推理和应该做的事情:
运算符const TemplateItem *();应该删除。
为什么呢?永远不会有一个实例需要将TestA(或任何模板类)隐式转换为具有未知大小的TemplateItem数组 - 因为它绝对没有边界检查(数组可以是sizeof 1或10或1000或0)和如果调用函数或类收到数组而不知道它的大小,可能会导致崩溃。
如果需要数组,可以使用operator []作为直接项,或者使用GetArray(这将指示用户打算传递未知长度的数组)。
保留运算符const std :: string。代码将编译。可避免的内存问题。
(Alf的努力被选为“正确的”答案,尽管这是更合乎逻辑的选择)