Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无法通过C+;中的隐式转换找到运算符+;_C++_Type Conversion_Operator Keyword_Implicit Conversion - Fatal编程技术网

C++ 无法通过C+;中的隐式转换找到运算符+;

C++ 无法通过C+;中的隐式转换找到运算符+;,c++,type-conversion,operator-keyword,implicit-conversion,C++,Type Conversion,Operator Keyword,Implicit Conversion,在编写一个类作为堆分配对象的包装器时,我遇到了隐式类型转换的问题,可以简化为这个简单的示例 在下面的代码中,包装器类管理堆分配的对象,并隐式转换为对该对象的引用。这允许包装器对象作为参数传递给函数write(…),因为会发生隐式转换 但是,编译器在尝试解析对运算符的调用时失败,请检查插入运算符的签名。。。我认为他们采用了非常量ostream参考 根据C++03标准确认,char*输出运算符的签名为: template<class charT, class traits> basic_

在编写一个类作为堆分配对象的包装器时,我遇到了隐式类型转换的问题,可以简化为这个简单的示例

在下面的代码中,包装器类管理堆分配的对象,并隐式转换为对该对象的引用。这允许包装器对象作为参数传递给函数write(…),因为会发生隐式转换


但是,编译器在尝试解析对运算符的调用时失败,请检查插入运算符的签名。。。我认为他们采用了非常量ostream参考

根据C++03标准确认,char*输出运算符的签名为:

template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
模板

basic_ostream&operator编译器没有足够的上下文来确定
运算符&
将进行有效转换。因此,是的,我认为这与参数相关的查找有关:编译器正在查找一个
操作符它失败了,因为您试图解析
包装器
类中不存在的操作符。如果您想让它在没有演员阵容的情况下工作,您可以组合如下内容:

template<typename X> wrapper<T> &operator <<(X &param) const {
    return t << param;
}

template wrapper&operator我认为问题与维护一些编译时约束有关。在您的示例中,编译器首先必须找到all可能的运算符,经过一些测试,一个更简单的示例确定了问题的根源。编译器无法从
wrapper
bar&
的隐式转换中推断下面
f2(const bar&)
中的模板参数
T

模板
类包装器
{
T*T;
公众:
显式包装器(T*const p):T(p){
~wrapper(){delete t;}
运算符T&()常量{return*T;}
};
类foo{};
模板类条{};
void f1(const foo&s){}
模板无效f2(常数条和s){}
void f3(常数条和常数条){}
int main()
{
包装器s1(newfoo());
f1(s1);
包装器s2(新条());
//f2(s2);//失败
f2(s2);//好的
f3(s2);
}

在最初的示例中,
std::ostream
实际上是模板化类
std::basic_ostream
typedef
,调用模板化函数
OperatorTanks时也适用同样的情况,但没有什么区别。转换运算符是一个常量成员函数,因为它不会更改指针t,但转换仍然是t&,而不是常量t&。这就像“const t*”和't*const’之间的区别。我最近指责C++不够。>在编译时解决返回类型,这将需要更高级的模板元编程…plus(可能)类型trails+SFINAE。这可能是一个很好的解决方法,但即使没有为包装器定义运算符+=,以下操作仍然有效:包装器i(newint(10));i+=1;//给出11由于int case是一个整型,而整型升级/转换更容易进行,因此int case可能会起作用?例如,如果我是+='ing一个int,它可能会试图将lhs也变成int?我喜欢这样的回答,这可能是我应该做的,尽管我可能会回包装纸而不是打电话给汤姆·邦。我知道:)您的opI完全缺少wrapper:fstream对象的值,这些对象是在堆栈上创建的,它们会在自身清理之后创建的。相反,您在堆上创建一个fstream对象,然后使用wrapper来保证它在与开始清理时完全相同的位置得到清理。在实际版本中,我使用boost::shared_ptr而不是T*,以便共享实例,并为共享实例实现必要的语义。这个例子大大简化了,不太现实,但足以说明问题。如果模板的参数是自动删除的,那么转换集是有限的。因此,在您的情况下,如果您希望使用模板void write(basic_ostream&);您也会遇到同样的问题(除了op中依赖于参数的查找之外)
template<typename X> wrapper<T> &operator <<(X &param) const {
    return t << param;
}
template <typename T>
class wrapper
{
    T* t;
  public:
    explicit wrapper(T * const p) : t(p) { }
    ~wrapper() { delete t; }
    operator T & () const { return *t; }
};

class foo { };

template <typename T> class bar { };

void f1(const foo& s) { }
template <typename T> void f2(const bar<T>& s) { }
void f3(const bar<int>& s) { }

int main()
{
    wrapper<foo> s1(new foo());
    f1(s1);

    wrapper<bar<int> > s2(new bar<int>());
    //f2(s2); // FAILS
    f2<int>(s2); // OK
    f3(s2);
}