Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates_Type Conversion - Fatal编程技术网

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;
}