开发者

Problem with return type

I have a classes:

    struct Policy_1
    {
        void signalFailure()
        {
            throw std::exception();
        }
    };

    struct Policy_2
    {
        void* signalFailure()
        {
            return nullptr;
        }
    };

    template<class Policy>
    struct My
    {    
        template<class T>
        T* fnc(int value)
        {
            if (!value)
            {
                return Policy::signalFailure();//Here is the problem
            }
            else
            {
                return new int(value);
            }
        }

    };

The problem is that depending on Policy class signalFailure either throws or returns nullptr but I'm getting error from compiler (even though Policy is set that it does throw) that it cannot convert void to (T*) - depending what I've substitute for tea; Now, I do understand where the problem lies - compiler does syntax check and discovers that from this Policy, signalFailure returns void so it can't parse it even though signalFailure in practice throws.

I have two options as I see it:

a) either declare vo开发者_开发技巧id* as a result type of signalFailure

b) declare void as a result type in fnc and move the result type to a args list of this fnc or

c) do some (and here is the real Q to you) macro or metaprogramming inside my fnc which would be determined at compile time (either return Policy::etc or just Policy::etc) and that I think would be the best option. Of course if someone of you has better and more elegant idea how to do it, is more than welcome to show it.


I see that you're using nullptr- which means that you must be in C++0x. In this case it is trivial to use decltype to solve this problem.

template<class Policy>
struct My
{
    template<typename T> struct func_helper {
         static T func() { return Policy::signalFailure(); }
    };    
    template<> struct func_helper<void> {
         static void* func() { Policy::signalFailure(); return nullptr; }
    };
    template<class T>
    T* fnc(int value)
    {
        if (!value)
        {
            return func_helper<decltype(Policy::signalFailure())>::func();
        }
        else
        {
            return new int(value); // Compile error if int* cannot be converted
                                   // to the type of the policy.
        }
    }

};

Edit: Hang on a second. This code is SERIOUSLY wrong. You're returning a new int(), as T*? This code doesn't need fixing, it needs the whole module ripping out.


I wouldn't be shocked if the throwing policy did have a return value, though unused, and that's probably what I would do. However, if you wan't to avoid void *, you could as well make the signalFailure methods template and call Policy::signalFailure<T>() from fnc (thus allowing the signalFailure methods to returned a more strongly typed T *).

On a side note, the signalFailure methods should either be static, or My should privately inherit from your Policy class.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜