Как узнать, что x
находится вне функции? (Он не может заглянуть в тело, потому что в , какое тело какой функции он смотрит, зависит от того, какое значение x
получает!). Также вы не можете написать это ?:
, потому что обе ваши ветви дают совершенно несвязанные типы, которые не могут получить общий тип. Но этот оператор требует наличия общего типа для обеих ветвей, которые он оценивает.
И еще одна проблема, с которой вы сталкиваетесь, size
не является постоянной времени компиляции, уже разработана другим постом.
Я думаю, что это должно работать:
template<int y, int z>
someclass<sizeof (char[+(y >= z)]) * y> anotherfunc(someclass<y> A, someclass<z> B){
return A;
}
template<int y, int z>
someclass<sizeof (char[+(y < z)]) * z> anotherfunc(someclass<y> A, someclass<z> B){
return B;
}
Теперь при его вызове y
и z
выводятся параметрами, а затем параметры подставляются в возвращаемый тип. sizeof(char[1 or 0])
проверит, больше ли y
или z
. В соответствующем шаблоне, который оценивает это как sizeof(char[1])
(что дает 1), мы умножим на значение, которое больше (или равно). Если соответствующий шаблон выдает sizeof(char[0])
, то это ошибка вывода (массив не может быть нулевого размера!), И шаблон не будет выбран по разрешению перегрузки (известному как SFINAE ).
Унарный +
дает 1
или 0
как int вместо true
или false
, что может вызвать предупреждения компилятора для некоторых компиляторов.
Существует также «чистый» способ с enable_if
. Это не делает отвратительные sizeof
трюки, а скорее использует общий установленный паттерн enable_if. Boost имеет реализацию этого
template<int y, int z>
typename boost::enable_if_c<(y >= z), someclass<y> >::type
anotherfunc(someclass<y> A, someclass<z> B){
return A;
}
template<int y, int z>
typename boost::enable_if_c<(y < z), someclass<z> >::type
anotherfunc(someclass<y> A, someclass<z> B){
return B;
}
На первый взгляд это может показаться более шумным, но должно быть проще для понимания и быстрее для людей, которые уже привыкли к enable_if
(вариант реализации Boost _c
принимает простые логические значения, как указано выше).