views:

120

answers:

1

Why compiler cannot specialize this function and is there a way to force him to do so?
The error I'm getting:
Error 1 error C2893: Failed to specialize function template ''unknown-type' Ternary::check(bool,Left,Right)'

#include "stdafx.h"
#include <iostream>
#include <string>
using std::cout;
using std::string;

template<int v>
struct Int2Type
{
    enum {value = v};
};

template<bool condition,class Left, class Right>
struct Result;


template<class Left, class Right>
struct Result<true,Left,Right>
{
    typedef Left value;
};

template<class Left, class Right>
struct Result<false,Left,Right>
{
    typedef Right value;
};

struct Ternary
{
    template<class Left, class Right>
    static Right check_(Int2Type<false>, Left left, Right right)
    {
        return right;
    }

    template<class Left, class Right>
    static Left check_(Int2Type<true>, Left left, Right right)
    {
        return left;
    }


__Updated__
    template<bool Condition,class Left, class Right>
static auto check(Left left, Right right)->
    typename Result<Condition,Left,Right>::value
{
    return check_(Int2Type<Condition>,left,right);
}

int _tmain(int argc, _TCHAR* argv[])
{
    int a = 5;
    string s = "Hello";
    cout << Ternary::check<false>(a,s);
    return 0;
}
+3  A: 

I don't have enough experience with C++0x yet, but from what I see:

    decltype(Result<(sizeof(int) == 1),Left,Right>::value)

decltype expects an expression, but Result<...>::value is a type. Just remove the decltype;

    return check_(Int2Type<condition>,left,right);

condition is a variable, you can't use it as a template parameter.

UPDATE: also Int2Type<Condition> is again a type. You want to pass a value: Int2Type<Condition>().

ybungalobill
@ybungalobill Similarly to the sizeof operator, the operand of decltype is unevaluated.[9] Informally, the type returned by decltype(e) is deduced as follows:[1]If the expression e refers to a __variable__ in local or namespace scope, a static member variable or a function parameter, then the result is that variable's or parameter's declared type If e is a function call or an overloaded operator invocation, decltype(e) denotes the declared return type of that function Otherwise, if e is an lvalue, decltype(e) is T if e is an rvalue, the result is T
There is nothing we can do
@There: It has nothing to do with evaluation. **Grammar** says that the thing between the parenthesizes must be an **expression**, what you wrote there is a **type**.
ybungalobill
@ybungalobill ok got it. But I can remove decltype - it wont compile
There is nothing we can do
@There: if it doesn't compile without decltype you may try to add `typename` before result (and remove decltype).
ybungalobill
@ybunalobill adding typename helped. Thanks. Now (I've updated my post) complianes about check_(...);
There is nothing we can do
@There: updated.
ybungalobill
@ybunalobill shaba daba fantastic! Great thanks!
There is nothing we can do