gpt4 book ai didi

c++ - 为什么 C++ 更喜欢这个模板方法而不是方法重载?

转载 作者:IT老高 更新时间:2023-10-28 23:19:31 25 4
gpt4 key购买 nike

假设我有两个类,第一个用于编写原始类型(boolintfloat 等),第二个一个扩展第一个也可以编写复杂类型:

struct Writer {
virtual void Write(int value) = 0;
};

struct ComplexWriter : public Writer {
template <typename TValue> void Write(const TValue &value) {
boost::any any(value);
Write(any);
}
//virtual void Write(int value) = 0; // see question below
virtual void Write(const boost::any &any) = 0;
};

这个想法是,如果有人调用 myWriter.Write(someIntValue);,int 重载将优先于模板化方法。

相反,我的编译器 (Visual C++ 11.0 RC) 总是选择模板方法。例如,下面的代码片段会将 Wrote any 打印到控制台:

struct ComplexWriterImpl : public ComplexWriter {
virtual void Write(int value) { std::cout << "Wrote an int"; }
virtual void Write(const boost::any &any) { std::cout << "Wrote any"; }
};

void TestWriter(ComplexWriter &writer) {
int x = 0;
writer.Write(x);
}

int main() {
ComplexWriterImpl writer;
TestWriter(writer);
}

当我在 ComplexWriter 类中声明 Write(int) 方法时,行为突然发生了变化(请参阅第一个片段中注释掉的行)。然后它将 Wrote an int 打印到控制台。

这是我的编译器应该如何表现的吗? C++ 标准是否明确规定只有在同一类(而不是基类)中定义的重载才能优先于模板化方法?

最佳答案

问题在于,在您调用 writer.Write(x) 时,编译器看到的是 ComplexWriter 而不是 ComplexWriterImpl,所以它只知道 ComplexWriter 中定义的函数——模板函数和 boost::any 函数。

ComplexWriter 不包含任何接受 int 的虚函数,因此无法调用 ComplexWriterImpl 中定义的 int 重载>

当您将虚拟重载添加到 ComplexWriter 类时,编译器会意识到 ComplexWriter 类中有一个整数重载,因此会调用它ComplexWriterImpl

中的实现

编辑:既然您已经在 ComplexWriter 和 Writer 之间的继承中进行了编辑,我有一个更完整的解释给您:

当您创建一个子类并在其中定义一个函数时,基类中该名称的所有函数都将被隐藏,无论其参数类型如何。

我相信你可以使用 using 关键字来解决这个问题:

struct ComplexWriter : public Writer {
template <typename TValue> void Write(const TValue &value) {
boost::any any(value);
Write(any);
}
using Writer::Write;
virtual void Write(const boost::any &any) = 0;
};

有关详细信息,请参阅此常见问题解答条目:http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9

编辑 2:只是为了确认这确实解决了您的问题:http://ideone.com/LRb5a

关于c++ - 为什么 C++ 更喜欢这个模板方法而不是方法重载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10931745/

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