gpt4 book ai didi

c++ - std::make_pair 类型推导

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:22:53 28 4
gpt4 key购买 nike

我遇到了一些奇怪的事情,我想得到解释。以下代码片段提供了一个简单的类模板 type和两个 operator<< s:一个用于 type 的特化和一个 std::pairtype特化。

#include <ostream>
#include <utility>

template <typename T>
class type {

public:

T value_;

};

template <typename CTy, typename CTr, typename T>
std::basic_ostream<CTy,CTr>&
operator<<(std::basic_ostream<CTy,CTr>& os, type<T> const& a)
{
return os << a.value_;
}

template <typename CTy, typename CTr, typename T>
std::basic_ostream<CTy,CTr>&
operator<<(std::basic_ostream<CTy,CTr>& os, std::pair<T const, T const> const& a)
{
return os << a.first << ',' << a.second;
}

#include <iostream>

int
main()
{
using float_type = type<float>;

float_type const a = { 3.14159 };
float_type const b = { 2.71828 };

#if 0
std::cout << std::make_pair(a, b)
<< std::endl;
#else
std::cout << std::pair<float_type const, float_type const>(a, b)
<< std::endl;
#endif
}

main函数提供一个特化和该特化的两个变量。将变量显示为 std::pair 有两种变体。 .第一个失败是因为 std::make_pair似乎剥离了 const来自变量的说明符,这又与第二个 operator<< 的签名不匹配: std::pair<T const, T const> .但是,构建一个 std::pair特化(std::cout 中的第二行 main )与删除 const 一样有效T 的规范来自 operator<<对于 std::pair ,即 std::pair<T, T> .

编译器消息::

  • 海湾合作委员会 4.9.2

    std_make_pair.cpp: In function 'int main()':
    std_make_pair.cpp:52:35: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
    std::cout << std::make_pair(a, b) << std::endl;
    ^
    In file included from std_make_pair.cpp:3:0:
    /usr/include/c++/4.9.2/ostream:602:5: note: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::pair<type<float>, type<float> >]'
    operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
    ^
  • clang 3.5(已删除系统 header 中的不可行函数)

    std_make_pair.cpp:52:13: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>')
    and 'pair<typename __decay_and_strip<const type<float> &>::__type, typename __decay_and_strip<const
    type<float> &>::__type>')
    std::cout << std::make_pair(a, b) << std::endl;
    ~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~

    std_make_pair.cpp:30:1: note: candidate template ignored: can't deduce a type for 'T' which would make
    'const T' equal 'type<float>'
    operator<<(std::basic_ostream<CTy,CTr>& os, std::pair<T const, T const> const& a)

所以,问题来了:我应该指定一个 operator<< 吗?服用std::pairT而不是 T const ?这不是在淡化我与该功能的任何用户(即 T const)签订的契约(Contract)吗?我基本上保证使用 T仅以非变异方式?

最佳答案

The first fails because std::make_pair seems to strip the const specifier from the variables, which in turn doesn't match with the signature of the second operator<<: std::pair<T const, T const>

没错。 make_pair是一个依赖 std::decay 的函数模板显式删除 const , volatile , 和 &预选赛:

template <class T1, class T2>
constexpr pair<V1, V2> make_pair(T1&& x, T2&& y);

Returns: pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y)); where V1 and V2 are determined as follows: Let Ui be decay_t<Ti> for each Ti. Then each Vi is X& if Ui equals reference_wrapper<X>, otherwise Vi is Ui.

编译器完全正确地拒绝了您的代码 - 您为 pair<const T, const T> 添加了流运算符, 但正在尝试流式传输 pair<T, T> .解决方案是只删除额外的 const您的流运算符(operator)中的要求。该函数中没有任何内容需要 pair包括const类型 - 只是类型本身是可流动的,这与它们的 const 无关尼斯。这没有错:

template <typename CTy, typename CTr, typename T>
std::basic_ostream<CTy,CTr>&
operator<<(std::basic_ostream<CTy,CTr>& os, std::pair<T, T> const& a)
{
return os << a.first << ',' << a.second;
}

已经参加了 pair通过引用常量,你无论如何都不能修改它的内容。

关于c++ - std::make_pair 类型推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29985791/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com