【发布时间】:2015-05-01 11:09:49
【问题描述】:
我遇到了一些奇怪的事情,我想解释一下。以下代码 sn -p 提供了一个简单的类模板 type 和两个 operator<<s:一个用于 type 的特化,一个用于 std::pair 的 type 特化。
#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 特化(main 中的第二个std::cout 行)以及从operator<< 中删除T 的const 规范对于std::pair,即std::pair<T, T>。
编译器消息::
-
gcc 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(从系统头文件中删除了不可行的函数)
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<< 以T 的std::pair 而不是T const?这不是淡化了我与该功能的任何用户建立的合同,即与T const 我基本上承诺仅以非变异方式使用T?
【问题讨论】:
-
我认为 std::pair 和 std::make_pair 不好(尤其是 std::map,其中 std::make_pair(key, value) 不提供 map::value_type)。
-
@marco-a 感谢您编辑编译器消息。文档不是很清楚如何做到这一点。你使用了
<!-- language: ... -->标签吗? -
@regnirpsj 不,当项目符号列表需要两倍的代码空间时。应该在某处说明。