C++ 模板推导/类型转换错误
我在模板推导/类型转换方面遇到问题。以下代码无法编译:C++ 模板推导/类型转换错误,c++,templates,type-conversion,C++,Templates,Type Conversion,我在模板推导/类型转换方面遇到问题。以下代码无法编译: template <typename Type> struct A { void DoA() { } }; struct B : public A<B> { void DoB() { } }; template <typename T> void DoSmth(const std::shared_ptr<A<T>> &p)
template <typename Type>
struct A
{
void DoA()
{
}
};
struct B : public A<B>
{
void DoB()
{
}
};
template <typename T>
void DoSmth(const std::shared_ptr<A<T>> &p)
{
p->DoA();
}
int _tmain(int argc, _TCHAR* argv[])
{
std::shared_ptr<B> pb(new B);
DoSmth(pb);
//std::shared_ptr<A<B>> pa(pb);
//DoSmth(pa);
return 0;
};
模板
结构A
{
无效DoA()
{
}
};
结构B:公共A
{
void DoB()
{
}
};
模板
void DoSmth(const std::shared_ptr&p)
{
p->DoA();
}
int _tmain(int argc,_TCHAR*argv[]
{
std::共享ptr pb(新B);
DoSmth(pb);
//std::共享的ptr pa(pb);
//DoSmth(pa);
返回0;
};
MSVC错误如下:
error C2664: 'void DoSmth<B>(const std::shared_ptr<A<B>> &)' : cannot convert argument 1 from 'std::shared_ptr<B>' to 'const std::shared_ptr<A<B>> &'
Binding to reference with added qualification
followed by
Call to constructor 'std::shared_ptr<A<B>>::shared_ptr<B,void>(const std::shared_ptr<B> &) throw()'
c:\program files (x86)\microsoft visual studio 12.0\vc\include\memory(531) : see declaration of 'std::shared_ptr<A<B>>::shared_ptr'
followed by
Binding to reference
错误C2664:'void DoSmth(const std::shared_ptr&'):无法将参数1从'std::shared_ptr'转换为'const std::shared_ptr&'
具有附加资格的引用约束
然后
调用构造函数'std::shared_ptr::shared_ptr(const std::shared_ptr&)throw()'
c:\ProgramFiles(x86)\microsoft visual studio 12.0\vc\include\memory(531):请参阅“std::shared\u ptr::shared\u ptr”的声明
然后
绑定到引用
GCC错误:
prog.cpp:28:11: error: no matching function for call to ‘DoSmth(std::shared_ptr<B>&)’
DoSmth(pb);
^
prog.cpp:21:6: note: candidate: template<class T> void DoSmth(const std::shared_ptr<A<T> >&)
void DoSmth(const std::shared_ptr<A<T>> &p)
^~~~~~
prog.cpp:21:6: note: template argument deduction/substitution failed:
prog.cpp:28:11: note: mismatched types ‘A<T>’ and ‘B’
DoSmth(pb);
^
prog.cpp:28:11:错误:对“DoSmth(std::shared_ptr&)”的调用没有匹配的函数
DoSmth(pb);
^
程序cpp:21:6:注:候选:模板无效DoSmth(const std::shared_ptr&)
void DoSmth(const std::shared_ptr&p)
^~~~~~
程序cpp:21:6:注意:模板参数扣除/替换失败:
程序cpp:28:11:注:类型“A”和“B”不匹配
DoSmth(pb);
^
注释代码不会出现问题(当手动完成转换时),如果i_a
不是模板类,也不会出现问题。我想知道,如果(根据错误消息)编译器已经推导出了模板类型(这样它应该与注释代码等效),为什么编译器不能进行转换
在不改变函数的参数类型的情况下(我迫切需要它是A
),我能做些什么吗?请注意,shared\u ptr
类仅用于说明问题,我实际上使用了另一个智能指针类,我可以轻松更改它(如果需要在那里进行更改)
还请注意,如果使用原始指针而不是智能指针,那么一切都像一个符咒 您可以显式地给出类型
int main()
{
std::shared_ptr<B> pb(new B);
DoSmth<B>(pb);
//-----^
}
intmain()
{
std::共享ptr pb(新B);
DoSmth(pb);
//-----^
}
这里的问题是,在中,void DoSmth(const std::shared_ptr)和约束模板
template <typename T>
void DoSmth(const std::shared_ptr<T> &p)
现在,我们可以将一个std::shared_ptr
传递给函数,而无需做任何额外的操作。下面的示例显示了它的工作原理,并且它拒绝了非派生类型的shared_ptr
:
#include <type_traits>
#include <memory>
template <typename Type>
struct A
{
void DoA()
{
}
};
struct B : public A<B>
{
void DoB()
{
}
};
struct Foo {};
template <typename T, typename = typename std::enable_if<std::is_base_of<A<T>, T>::value>::type>
void DoSmth(const std::shared_ptr<T> &p)
{
p->DoA();
}
int main()
{
std::shared_ptr<B> pb(new B);
DoSmth(pb); // this compiles
std::shared_ptr<Foo> pf(new Foo);
DoSmth(pf); // this will generate a compiler error
//std::shared_ptr<A<B>> pa(pb);
//DoSmth(pa);
return 0;
}
#包括
#包括
模板
结构A
{
无效DoA()
{
}
};
结构B:公共A
{
void DoB()
{
}
};
结构Foo{};
模板为什么它会知道你需要一个DoSmth
?也许你可以继承a
和a
,而不是你期望它产生什么?这也不是一个选项,我正在考虑使用enable\u if
,但我认为可能还有其他方法。奇怪的是,根据错误消息sage,编译器(至少MSVC)已推导出所需的类型,但无法进行转换。事实上,我有点错误-我还需要DoSmth(pf);
进行编译,但要编译不同的template@ArtyomChirkov你可能需要问一个新问题,然后详细说明你有什么和你想要什么。
#include <type_traits>
#include <memory>
template <typename Type>
struct A
{
void DoA()
{
}
};
struct B : public A<B>
{
void DoB()
{
}
};
struct Foo {};
template <typename T, typename = typename std::enable_if<std::is_base_of<A<T>, T>::value>::type>
void DoSmth(const std::shared_ptr<T> &p)
{
p->DoA();
}
int main()
{
std::shared_ptr<B> pb(new B);
DoSmth(pb); // this compiles
std::shared_ptr<Foo> pf(new Foo);
DoSmth(pf); // this will generate a compiler error
//std::shared_ptr<A<B>> pa(pb);
//DoSmth(pa);
return 0;
}