为什么类型别名决定输出是左值还是右值?
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&
)。
出于测试目的,我创建了一个包含两个静态函数的结构。 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&
)。