Тернарный оператор

Почему компилятор не может специализировать эту функцию и есть ли способ заставить его это сделать?
Я получаю сообщение об ошибке:
Ошибка 1 error C2893: Не удалось специализировать шаблон функции "неизвестный тип" Тернарный::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;
}

person There is nothing we can do    schedule 02.10.2010    source источник
comment
@Prasoon Saurav C++03 его можно рассматривать как подмножество C++0x, поэтому ваше редактирование неуместно для C++0x.   -  person There is nothing we can do    schedule 02.10.2010
comment
Да, но ТАК не так ярко. Если вы ищете вопросы с тегом c++, SO не будет перечислять этот вопрос.   -  person Mike DeSimone    schedule 02.10.2010
comment
На decltype с g++ 4.5 нет ошибки. Он жалуется только на строку check_(Int2Type<condition>,left,right);.   -  person kennytm    schedule 02.10.2010
comment
@KennyTM под соответствием вы имеете в виду предупреждает или выдает ошибку?   -  person There is nothing we can do    schedule 02.10.2010
comment
@ Там: ошибки, конечно. Параметр шаблона должен быть постоянным выражением.   -  person kennytm    schedule 02.10.2010


Ответы (1)


У меня пока недостаточно опыта работы с C++0x, но из того, что я вижу:

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

decltype ожидает выражение, а Result<...>::value — это тип. Просто удалите decltype;

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

condition — это переменная, вы не можете использовать ее как параметр шаблона.

ОБНОВЛЕНИЕ: также Int2Type<Condition> снова является типом. Вы хотите передать значение: Int2Type<Condition>().

person Yakov Galka    schedule 02.10.2010
comment
@ybungalobill Как и в случае с оператором sizeof, операнд decltype не оценивается.[9] Неформально тип, возвращаемый decltype(e), выводится следующим образом:[1] Если выражение e ссылается на переменную в локальной области или области имен, статической переменной-члене или параметре функции, результатом является объявленный тип этой переменной или параметра. Если e является вызовом функции или вызовом перегруженного оператора, decltype(e) обозначает объявленный тип возвращаемого значения этой функции. В противном случае, если e является lvalue, decltype(e) равен T&, где T равен тип е; если e является значением r, результатом будет T - person There is nothing we can do; 02.10.2010
comment
@ Там: это не имеет ничего общего с оценкой. Грамматика говорит, что то, что заключено в скобки, должно быть выражением, то, что вы там написали, является типом. - person Yakov Galka; 02.10.2010
comment
@ybungalobill хорошо понял. Но я могу удалить decltype - он не скомпилируется - person There is nothing we can do; 02.10.2010
comment
@ Там: если он не компилируется без decltype, вы можете попробовать добавить typename перед результатом (и удалить decltype). - person Yakov Galka; 02.10.2010
comment
@ybunalobill помогло добавление имени типа. Спасибо. Теперь (я обновил свой пост) соответствует check_(...); - person There is nothing we can do; 02.10.2010