Шаблон признаков типа C++ для добавления ссылки, если не const
У меня есть шаблон класса, который принимает тип T
. У него есть метод. Я хочу, чтобы этот метод возвращал тип T
, если это const
и T&
, Если это неconst
.
template<typename T>
class C
{
static typename add_reference_if_non_const<T>::type method();
};
int main()
{
assert( is_same<result_of<C<int>::method()>::type, int&>::value );
assert( is_same<result_of<C<const int>::method()>::type, const int>::value );
}
Как я могу это сделать?
2 ответа:
Вы хотите, чтобы возвращаемый тип
Учитывая это, я думаю, что вы хотите следующееC<int const>::method()
былint const
, но квалификаторы cv верхнего уровня игнорируются в типах возвращаемых функций. В любом случае, посколькуmethod()
возвращает копиюT
, Вас действительно волнует, что вы возвращаетеT const
, а неT
?using add_reference_if_non_const = typename std::conditional<std::is_const<T>{}, typename std::remove_const<T>::type, typename std::add_lvalue_reference<T>::type >::type; static add_reference_if_non_const method();
Вы можете заменить
typename std::remove_const<T>::type
наT
, Если хотите вернутьT const
, КогдаT
является типом класса.
Следующая проблема связана с
result_of
что работает с типом аргументы; то, что вы имеете в вопросе, является вызовом функцииC::method
. Вам нужно использоватьНо поскольку вам все равно нужно использоватьresult_of<decltype(&C<int>::method)()>::type
decltype
, вы можете полностью избавиться отresult_of
.decltype(C<int>::method())
Наконец, вам не нужно
assert
во время выполнения, когда вы можете выполнять проверки во время компиляции с помощьюstatic_assert
static_assert( is_same<decltype(C<int>::method()), int&>::value, ""); static_assert( is_same<decltype(C<int const>::method()), int>::value, "" );