gpt4 book ai didi

c++ - 使用用户定义的转换运算符的函数模板重载决议

转载 作者:太空狗 更新时间:2023-10-29 21:15:41 26 4
gpt4 key购买 nike

根据 C++11 标准,以下代码的正确输出是什么?

#include <iostream>

template <typename X>
class A
{
public:
A()
{
std::cout << "A::A" << std::endl;
}
A(const A<X>&)
{
std::cout << "A::A(const A<X>&)" << std::endl;
}
A<X>& operator = (const A<X>&)
{
std::cout << "A::opeartor =(conat A&)" << std::endl;
return *this;
}
};

void* GetData()
{
// return data based on some condition
static A<int> a;
return &a;
}

class P
{

public:
template <typename T>
operator T&()
{
void* pData = GetData();
std::cout << "P::operator T&()" << std::endl;
return *(reinterpret_cast<T*>(pData));
}

operator A<int>()
{
std::cout << "P::opeartor A<int>" << std::endl;
return A<int>();
}
};

int main(int /*argc*/, char** /*argv*/)
{
P objP;
A<int> objA = objP; // case 1
objA = objP; // case 2
return 0;
}

clang 和 gcc 产生以下输出。

P::opeartor A<int>
A::A
A::A
P::operator T&()
A::opeartor =(conat A&)

VS 2015 生成如下所示的输出。

A::A
P::operator T&()
A::A(const A<X>&)
P::operator T&()
A::opeartor =(conat A&)

案例一

VS2015 选择模板版本,而 gcc 和 clang 选择非模板版本。

案例二

所有三个编译器都选择模板版本。

我们如何引用 C++ 11 标准来解释这种行为?

最佳答案

MSVC 错误。此处的行为取决于目标类型是否为引用类型,这会影响候选函数集。

  • 在对象(A<int> objA = objP;)的复制初始化中,适用于[dcl.init]/17中的规则表示目标类型是 A<int>候选集受 [over.match.copy] 管辖, 根据其规则,它包括两个转换函数;它们是并列的,模板/非模板决胜局选择非模板。

  • 在初始化引用const A<int>& (operator= 的参数),[dcl.init.ref]/5适用,这表示您首先使用 [over.match.ref] 指定的候选集进行重载决策,在初始化对象的左值引用时,它仅包括返回引用的转换函数。

    因此在这种情况下,唯一的候选者是模板;它被证明是可行的并被选中。甚至不考虑非模板。

这也意味着 A<int> objA(objP);将使用该模板,因为您在那里对 A<int> 的构造函数进行重载解析, 并将尝试初始化 const A<int>& A<int> 的参数的复制构造函数。

关于c++ - 使用用户定义的转换运算符的函数模板重载决议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37065520/

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