常量指针和常量数组的输出结果

4
当我们有两个操作符用于输出对象和这些对象的数组,并尝试输出常量对象的数组时,会涉及到对象的操作符。是否有一种方法可以强制数组的操作符与常量对象的c数组一起工作?
示例代码:
#include <iostream>
#include <cstddef>

using std::size_t;

namespace nm
{
  struct C { int i; };

  template <size_t N>
  using c_c_array = C[N];

  inline std::ostream& operator << (std::ostream& lhs,  C const*) { return lhs << "1\n"; }

  template <size_t N>
  inline std::ostream& operator << (std::ostream& lhs,  c_c_array<N> const&) { return lhs << "2\n"; }

}

int main()
{
  nm::C c{1};

  nm::C arr[5];

  nm::C const c_const{1};

  nm::C const arr_const[5] {{1}, {1}, {1}, {1}, {1}};

  std::cout << &c   // 1 - ok
            << arr  // 2 - ok
            << &c_const   // 1 - ok
            << arr_const; // 1 --ups

  return 0;
}

输出:1 2 1 1

此外,在我的情况下,运算符“2”用于输出“1”。


1
在您的代码中添加初始化器,以便人们停止回答错误的问题,例如 c_const{};arr_const[5]{}; - Rostislav
无论如何初始化,对于所提出的问题都不重要。 如果未初始化或初始化,则将调用运算符1。 这只是一个示例,我不会为任何事情使用该常量,仅用于说明运算符被调用的顺序。 - Роман Коптев
你的原始代码在在线编译器中无法编译(例如:http://cpp.sh/9ygc)。为了修复它,你不需要添加所有你所做的东西。你只需要在两行代码中加上“{}”即可。现在示例已经编译成功,你可能会得到你实际提出的问题的答案。 - Rostislav
我的原始代码是使用gcc 5.1编写的,没有使用gnu扩展,并且使用了-Weffc++ -Wextra -Wall进行编译。我使用了-std=c++14。但实际上,这个问题并不需要编写代码。我写代码只是因为我的帖子总是被编辑成具有控制台输出等工作示例。 - Роман Коптев
好的。我刚刚测试了几个在线编译器。我的代码将在任何版本的gcc中运行,从4.9.0开始,使用-std=c++14,并且从我所发现的情况来看,gcc 4.7.3与c++11兼容。GCC永远不会出现空类的错误,而clang会。我会记住这一点以备将来之需。 - Роман Коптев
显示剩余3条评论
2个回答

1
根据N4527草案标准8.5/p7.3 Initializers [dcl.init](强调我的),如下:

  • 否则,不执行初始化。

如果程序要求对const限定类型T的对象进行默认初始化,则T必须是具有用户提供的默认构造函数的类类型。

因此,您需要为class C定义一个默认构造函数才能使其正常工作。


1

目前我会做类似下面展示的事情。如果有更好的解决方案,请写下来。

#include <iostream>
#include <cstddef>
#include <type_traits>

using std::size_t;

namespace nm
{
  struct C { int i; };

  template <size_t N>
  using c_c_array = C[N];

  template<typename T>
  inline
  std::enable_if_t<std::is_same<T, C*>::value || std::is_same<T, C const*>::value,
  std::ostream&>
  operator << (std::ostream& lhs,  T const&) { return lhs << "1\n"; }

  template <size_t N>
  inline std::ostream& operator << (std::ostream& lhs,  c_c_array<N> const&) { return lhs << "2\n"; }

}

int main()
{
  nm::C c{1};

  nm::C arr[5];

  nm::C const c_const{1};

  nm::C const arr_const[] {1,2,3,4,5};

  std::cout << &c   // 1 - ok
            << arr  // 2 - ok
            << &c_const   // 1 - ok
            << arr_const; // 1 --ups

  return 0;
}

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