为什么没有必要的资格?

Che*_*Alf 13 c++

好吧,我会发布完整的程序,即使它有无关的东西,而且有问题的代码是死代码......

#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;
}
Run Code Online (Sandbox Code Playgroud)

这与MSVC和g ++编译良好.但在InFStream课堂上,为什么我不需要资格ios_base?或者,同样的问题,为什么我需要在构造函数初始化列表中使用std::限定条件ifstream

CB *_*ley 7

不同之处在于,ifstream作为注入的类名称不可见,因为它是a的名称typedef,而不是名称class.因此,作为基类中的注入类名,它不可视为不合格.

ios_base 是一个真正的类名,它是使用它的类的基类(基类),因此作为注入类名可见不合格.

例如

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.
};
Run Code Online (Sandbox Code Playgroud)

在您的示例中std::ifstream,您可以使用不合格,basic_ifstream而不是.(或者,basic_ifstream<char>basic_ifstream<char, std::char_traits<char> >但这些真的不保存任何打字或帮助的清晰度都没有.)


a1e*_*x07 6

关于为什么必须std::ifstream在构造函数的初始化程序中指定的一些想法.我认为typedef是罪魁祸首 - ifstream被定义为typedef basic_ifstream<char, char_traits<char> > ifstream;).如果您将构造函数更改为

 explicit InFStream(
    char const*         filename,
    ios_base::openmode  mode =  ios_base::in | ios_base::out

    ):
    basic_ifstream<char,std::char_traits<char>>( filename, mode ){}
Run Code Online (Sandbox Code Playgroud)

你也没必要指定std::basic_ifstream.我找不到有关为什么这样typedef工作的细节,但问题是可重现的.例如,

namespace test1
{
class A {

public :
    static const int cn = 1;

    virtual ~A();
    A(int t): x(t){};
    int x;
};

class B:public A
{
public:
    B(int t) : A(t){};
};
typedef B XX;  
};  
class C:public test1::XX
{
  int aaa;
    public:
explicit  C(int x) :XX(x) // error  
explicit  C(int x) :test1::XX(x) // ok
explicit  C(int x) :B(x) // also ok
{       
    aaa = A::cn;
};
};
Run Code Online (Sandbox Code Playgroud)