How to use widen()

I have a hard time figuring out the idea behind the narrow() and widen() functions. In particular, which encoding is assumed for the argument to widen(). I'll try to ask this way:


Let GLYPH stand for some specific glyph from the basic source character set, e.g. 'A'.

Let LITERAL stand for the character encoding used by the compiler to encode narrow character literals (e.g. US-ASCII).

Assume a specific but arbitrary locale.

Let MULTIBYTE be the multibyte character encoding that the locale assigns to narrow characters (e.g. UTF-8).

Let WIDE be the character encoding that the loclae assigns to wide characters (e.g. UCS-4).


Which of the following two descriptions of ctype<wchar_t>::widen(char) is then most correct?


1) Let c be the encoding of GLYPH with respect to the LITERAL encoding. The result of ctype<wchar_t>::widen(c) is then the encoding of GLYPH with respect to the WIDE encoding.

2) Let c be the encoding of GLYPH with respect to the MULTIBYTE encoding. Since GLYPH is in the basic source character set, it can always be represented as a single byte. The result of ctype<wchar_t>::widen(c) is then the encoding of GLYPH with respect to the WIDE encoding.


I understand that in most cases the distinction between these two meanings is unimportant, but I'd really like to know which of the two comes closest to the originally intended function of widen().



What I'd really like to know, is this:

The task is to write out an integer on a stream, surrounded by parentheses, and I want to do this in a completely general and portable way.

Is that even possible?

Is this the way to do it:

1
2
3
4
void parenthesize(std::wostream &out, int i)
{
  out << out.widen('(') << i << out.widen(')');
}

The wostream calls widen() for you automatically. Just say
1
2
3
4
void parenthesize(std::wostream &out, int i)
{
  out << '(' << i << ')';
}

You can use templates to increase portability:
1
2
3
4
5
template <typename T>
void parenthesize(std::wostream &out, const T &x)
{
  out << '(' << x << ')';
}

Finally, if you want some fun, you can do it pretty like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>

template <typename T>
struct parenthesize_t
  {
  const T& value;
  parenthesize_t( const T& value ): value( value ) { }
  };

template <typename T>
parenthesize_t <T>
parenthesize( const T& value )
  {
  return parenthesize_t <T> ( value );
  }

template <typename Char, typename Traits, typename T>
std::basic_ostream <Char, Traits> &
operator << (
  std::basic_ostream <Char, Traits> & outs,
  const parenthesize_t <T>          & value
  ) {
  return outs << '(' << value.value << ')';
  }

int main()
  {
  using namespace std;

  long  x = -7;
  float f = 3.141592;

  cout  << parenthesize( x ) << endl;
  wcout << parenthesize( f ) << endl;
  cout  << parenthesize( "Hello world!" ) << endl;

  return 0;
  }
This works by creating a special value that you pass to the insertion operator (<<).

Have fun!

[edit] Oh, I forgot to mention that the standard widen() function doesn't do squat. You need to specialize your streams to get anything better.
Last edited on
Are you saying that widen() is guaranteed by the standard to do nothing except casting to a wider type, and that this os true on any locale as long as the stream is either std::ostream or std::wostream?

EDIT: Assuming, of couse, that the locale does not violate any of the rules put forward by the standard.
Last edited on
Still, I'd really like to know what is the intention behind widen(). Is it (1) or (2) from above that describes it best? Or does my question perhaps make no sense?
Topic archived. No new replies allowed.