好的,我将发布完整的程序,即使它有无关的内容并且有问题的代码是死代码......
#include <iostream>
#include <fstream>
namespace detail {
// Solution by Johannes Schaub alias litb
// http://groups.google.com/group/comp.std.c++/browse_thread/thread/b567617bfccabcad
template<int> struct D {};
typedef char yes[1];
typedef char no[2];
template< class T, class U >
yes& f( int, D< sizeof T(*(U*)0) >* = 0 );
template< class T, class U >
no& f( ... );
template< class To, class From >
struct IsExplicitlyConvertible
{
enum{ yes = (sizeof detail::f< To, From >(0) == sizeof( detail::yes ) ) };
};
bool const streamsSupportWindows =
IsExplicitlyConvertible< std::ofstream, wchar_t const* >::yes;
}
class InFStream
: public std::ifstream
{
public:
InFStream() {}
explicit InFStream(
char const* filename,
ios_base::openmode mode = ios_base::in | ios_base::out
)
: std::ifstream( filename, mode )
{}
};
int main()
{
using namespace std;
cout << (detail::streamsSupportWindows
? "Windows-enabled"
: "Ach, no Windows support"
) << endl;
}
这可以很好地与 MSVC 和 g++ 一起编译。但在InFStream
类,为什么我不需要资格ios_base
?或者,同样的问题,为什么我需要使用std::
的资格ifstream
在构造函数初始值设定项列表中?
不同之处在于ifstream
作为注入的类名不可见,因为它是typedef
,不是名字class
。因此,它作为来自基类的注入类名不可见。
ios_base
是一个真正的类名,它是使用它的类的基类(基类的),因此作为注入类名可见且不合格。
E.g.
namespace X
{
class A {};
template<class> class Z {};
typedef Z<char> B;
}
class C : public X::A
{
C() : A() {} // OK, A is visible from the base class
};
class D : public X::B
{
D() : B() {} // Error, B is a typedef,
// : X::B(), : Z<char>() or even : Z() can be used.
};
在你的例子中,而不是std::ifstream
,您可以使用不合格的basic_ifstream
反而。 (或者basic_ifstream<char>
or basic_ifstream<char, std::char_traits<char> >
但这些并不能真正节省任何打字或帮助清晰。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)