Почему псевдоним типа определяет, является ли выход L-значением или R-значением? - PullRequest
0 голосов
/ 19 ноября 2018

Я создал структуру с двумя статическими функциями для тестирования.Первый экземпляр f вызывается, когда передается l-value reference.Второй экземпляр вызывается, когда передается r-value:

template <typename _Tp>
struct T {
    static constexpr void f(_Tp&) { std::cout <<  "f(T&)  is called!\n"; }
    static constexpr void f(_Tp&&) { std::cout << "f(T&&) is called!\n"; }
};

Когда я экспериментировал с strong types, я обнаружил, что первый экземпляр, T::f(_Tp&) был вызван, когда я попытался создать сильныйвведите неявно.Почему это?(См. Ниже)

using T_int = T<int>;

T_int::f(
    typename strong_types::create_strong_type<int, struct tag>(5)()
); // calls f::(T&) (?)

using KG = typename strong_types::create_strong_type<double, struct KG_tag>;
T_int::f(KG(4.2)()); // calls f(T&&)

Обратите внимание, что operator() возвращает значение, данное через конструктор.

Не стесняйтесь спрашивать, если мне нужно уточнить.

РЕДАКТИРОВАТЬ:strong_types это пространство имен.Существует среди прочего псевдоним create_strong_type:

namespace strong_type {
    template <typename T, typename tag>
    using create_strong_type = Strong_Type<T, tag>;

    ...
}

...

template <typename T, typename tag>
struct Strong_Type {
    constexpr explicit Strong_Type(const T& value) : _value(value) {}
    constexpr explicit Strong_Type(T&& value) : _value(std::move(value)) {}

    constexpr T& operator()() noexcept { return _value; }

private:
    T _value;
};

1 Ответ

0 голосов
/ 19 ноября 2018

Разница не в использовании псевдонима (using), а в типе, который вы передаете в качестве первого аргумента шаблона в create_strong_type. В одном случае это int, а в другом double.

Попробуйте T<double>::f(KG(4.2)());, и вы увидите, что аргумент передается как ссылка lvalue (из-за типа возврата Strong_Type::operator(), который T&).

...