为什么类型别名决定输出是左值还是右值?

Why does type aliasing determine whether output is L-value or R-value?

出于测试目的,我创建了一个包含两个静态函数的结构。 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()returns通过构造函数给出的值

欢迎询问我是否需要详细说明。

编辑: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;
};

差异不是因为使用了别名 (using),而是因为您作为第一个模板参数传递给 create_strong_type 的类型。在一种情况下,它是 int,在另一种情况下,它是 double.

尝试T<double>::f(KG(4.2)());,您会看到参数作为左值引用传递(因为Strong_Type::operator() 的return 类型,即T&)。