gpt4 book ai didi

c++ - 为什么这个构造函数重载不起作用? (发生模板和类型定义)

转载 作者:太空狗 更新时间:2023-10-29 23:16:19 24 4
gpt4 key购买 nike

我使用 VS2012 作为编译器。

首先有一个typedef由于缺少 template aliasing

template <typename T>
struct HvVector
{
typedef std::vector<T> rt;
};

然后我想实例化这个类的对象:

class LetYouDo
{
public:
template<typename CLASS, typename TYPE>
LetYouDo(const std::string& name, TYPE (CLASS::*field))
{
std::cout << "3" << std::endl;
}

template<typename CLASS, typename TYPE>
LetYouDo(const std::string& name, typename HvVector<TYPE>::rt (CLASS::*field), TYPE* p)
{
std::cout << "4" << std::endl;
}
};

使用示例类:

class Victim
{
public:
int m1;
HvVector<int>::rt m2;
};

所以真实情况是这样的:

Victim v;
v.m1 = 10;
v.m2.push_back(10);
LetYouDo o1("m1", &Victim::m1);
LetYouDo o2("m2", &Victim::m2, static_cast<int*>(0));

但是编译器报错:

error C2660: 'LetYouDo::LetYouDo' : function does not take 3 arguments

所以看起来编译器不知道我的第二个构造函数,为什么?

额外的TYPE* p是试图为编译器提供我的真实类型,因为 typedef输入 HvVector<TYPE>::rt除非我明确指定,否则无法推断出模板参数类型。

编辑:

这是一个在线测试代码,可以很好地与 gcc 4.8.1 配合使用,所以我认为这是VS2012的问题:ideone.com/YawsaB

最佳答案

问题出在构造函数完成的类型推导上。您可以通过使类成为模板而不是其构造函数来显式地创建类型。这有效:

template<typename CLASS, typename TYPE>
class LetYouDo
{
public:
LetYouDo(const std::string& name, TYPE (CLASS::*field))
{
std::cout << "3" << std::endl;
}

LetYouDo(const std::string& name, typename HvVector<TYPE>::rt (CLASS::*field), TYPE* p)
{
std::cout << "4" << std::endl;
}
};

LetYouDo<Victim,int> o1("m1", &Victim::m1);
LetYouDo<Victim,int> o2("m2", &Victim::m2, static_cast<int*>(0));

如果将构造函数转换为方法,您将看到来自编译器的正确消息。尝试:

class LetYouDo
{

template<typename CLASS, typename TYPE>
void LetYouDoInit(const std::string& name, typename HvVector<TYPE>::rt (CLASS::*field), TYPE* p)
{
std::cout << "4" << std::endl;
}
};

LetYouDo o2;
o2.LetYouDoInit("m2", &Victim::m2, static_cast<int*>(0));

您将获得:

1>c:\users\all\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp(47): error C2784: 'void LetYouDo::LetYouDoInit(const std::string &,HvVector<TYPE>::rt CLASS::* ,TYPE *)' : could not deduce template argument for 'HvVector<TYPE>::rt CLASS::* ' from 'std::vector<T,std::allocator<_Ty>> Victim::* '
1> with
1> [
1> T=int
1> , _Ty=int
1> ]
1> c:\users\all\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp(24) : see declaration of 'LetYouDo::LetYouDoInit'
1>c:\users\all\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp(47): error C2780: 'void LetYouDo::LetYouDoInit(const std::string &,TYPE CLASS::* )' : expects 2 arguments - 3 provided
1> c:\users\all\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp(18) : see declaration of 'LetYouDo::LetYouDoInit'

如果您将类型明确化,该消息将消失:

LetYouDo o2;
o2.LetYouDoInit<Victim,int>("m2", &Victim::m2, static_cast<int*>(0));

关于c++ - 为什么这个构造函数重载不起作用? (发生模板和类型定义),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24693273/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com