0

「不完全な型の無効な使用」に関連するトラブルなしで次を実装するにはどうすればよいですか?

class A { // line#10
    /*(...) some fields and methods here. */
    // more fields of the following functionality exist, storing data about object A's state.
    int SomeField;
    class Exception {
        /*(...) some fields and methods here. */
        public: enum ProblemCase { /*(...) */ };
        protected: Exception( ProblemCase issue, int additionalData ) { /*(...)*/ } // line#29
        friend Exception A::BuildException( ProblemCase ); // line#34
    };
    inline Exception BuildException( Exception::ProblemCase issue ) {
        return Exception( issue, SomeField ); // line#99
    }
};

更新: エラーログ:

A.hpp:34:72: error: invalid use of incomplete type ‘class A’
A.hpp:10:7: error: forward declaration of ‘class A’
A.hpp: In member function ‘A::Exception A::BuildException(A::Exception::ProblemCase)’:
A.hpp:29:20: error: ‘A::Exception::Exception(A::Exception::ProblemCase, int)’ is protected
A.hpp:99:46: error: within this context

名前が変更されたため、エラー ログの文字数が正しくないことに注意してください。

4

3 に答える 3

0

「学術的な」例として、私が得ることができる最も近いものです。注: 推奨されません。

#include <type_traits>

struct A { // line#10
    /*(...) some fields and methods here. */
    // more fields of the following functionality exist, storing data about object A's state.
    int SomeField;

    class Exception;

    template < typename T >
    inline Exception BuildException( T issue );

    class Exception {
        /*(...) some fields and methods here. */
        public: enum ProblemCase { FIRST /*(...) */ };
        protected: Exception( ProblemCase issue, int additionalData ) { /*(...)*/ } // line#29
        // accepted by clang, not by g++??
        // friend Exception A::BuildException<ProblemCase>( ProblemCase ); // line#34

        // accepted by both
        template < typename T >
        friend Exception A::BuildException( T ); // line#34
    };
};

// there's no need to define it outside the class
// (I originally used an explicit specialization)
template < typename T >
A::Exception A::BuildException( T issue ) {
    // optional
    static_assert(std::is_same<typename std::remove_const<T>::type, Exception::ProblemCase>::value, "Wrong type!");

    return Exception( issue, SomeField ); // line#99
}

int main()
{
    A a;
    a.BuildException(A::Exception::FIRST);
}
于 2013-05-05T21:23:06.277 に答える