为什么类型混叠确定输出是L值还是R值?

时间:2018-11-19 16:57:38

标签: c++ reference c++14 lvalue type-alias

出于测试目的,我创建了一个具有两个静态函数的结构。传递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 :(得分:1)

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

尝试T<double>::f(KG(4.2)());,您将看到参数作为左值引用传递(由于返回类型为Strong_Type::operator(),即T&)。