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

3

我创建了一个包含两个静态函数的结构体,用于测试目的。当传递一个左值引用时,会调用第一个 f 实例。当传递一个右值时,会调用第二个实例。

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"; }
};

在我尝试使用强类型进行实验时,我发现当我试图隐式创建强类型时,第一个实例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;
};

3
strong_types 是什么?答:strong_types 是什么? - Piotr Skotnicki
当然,但它是第三方库吗? - Piotr Skotnicki
1
另外无关的是:以下划线开头,后跟大写字母的标识符是保留的,您不允许使用它们。 - user10605163
你的测试用例使用了不同的基础类型,因此你不能得出类型别名是决定因素的结论。 - molbdnilo
1
请修复你的编辑中的拼写错误,标识符不匹配,例如 strong_typestrong_typesStrong_Type,可能应该是命名空间的一部分,并且在 create_strong_type 之前?即使慷慨地移动代码,它也无法编译。 - user10605163
显示剩余3条评论
1个回答

1
区别不在于使用别名(using),而在于你作为create_strong_type的第一个模板参数传递的类型。在一个情况下,它是一个int,而在另一个情况下,它是一个double
尝试T<double>::f(KG(4.2)());,你会发现参数被传递为左值引用(因为Strong_Type::operator()的返回类型是T&)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接