【发布时间】:2009-12-28 20:04:26
【问题描述】:
我花了一些时间删除所有不流畅的代码,这是我的问题。
--- File.h ---
#include <fstream>
#include <string>
template <typename Element>
class DataOutput : public std::basic_ofstream<Element>
{
public:
DataOutput(const std::string &strPath, bool bAppend, bool bBinary)
: std::basic_ofstream<Element>(
strPath.c_str(),
(bAppend ? ios_base::app : (ios_base::out | ios_base::trunc)) |
(bBinary ? ios_base::binary : 0))
{
if (is_open())
clear();
}
~DataOutput()
{
if (is_open())
close();
}
};
class File
{
public:
File(const std::string &strPath);
DataOutput<char> *CreateOutput(bool bAppend, bool bBinary);
private:
std::string m_strPath;
};
--- File.cpp ---
#include <File.h>
File::File(const std::string &strPath)
: m_strPath(strPath)
{
}
DataOutput<char> *File::CreateOutput(bool bAppend, bool bBinary)
{
return new DataOutput<char>(m_strPath, bAppend, bBinary);
}
--- main.cpp ---
#include <File.h>
void main()
{
File file("test.txt");
DataOutput<char> *output(file.CreateOutput(false, false));
*output << "test"; // Calls wrong overload
*output << "test"; // Calls right overload!!!
output->flush();
delete output;
}
这是使用cl 和选项/D "WIN32" /D "_UNICODE" /D "UNICODE" 构建并运行后的输出文件
--- test.txt ---
00414114test
基本上发生的情况是main 中的第一个operator<< 调用绑定到成员方法
basic_ostream<char>& basic_ostream<char>::operator<<(
const void *)
而第二个(正确)绑定到
basic_ostream<char>& __cdecl operator<<(
basic_ostream<char>&,
const char *)
从而给出不同的输出。
如果我执行以下任何操作,则不会发生这种情况:
- 内联
File::CreateOutput - 将
DataOutput更改为非模板的Element=char - 在第一个
operator<<调用之前添加*output;
我认为这是不受欢迎的编译器行为是否正确?
对此有什么解释吗?
哦,我现在正在使用 VC7 来测试这个简化的代码,但是我已经在 VC9 和 VC8 中尝试过原始代码,并且发生了同样的事情。
感谢任何帮助甚至线索
【问题讨论】:
-
这是一个明确的编译器错误。顺便说一句,它也可以在 VS2010 beta2 上重现。正如所写,这已经是一个很棒的错误报告——你可以将它发布到connect.microsoft.com/VisualStudio/feedback。
-
我会尽快的。至少我没有白白浪费这些时间
标签: c++ visual-c++ operator-overloading c++-standard-library