- PR -

C++におけるConsole::WriteLine()について

1
投稿者投稿内容
MUSE
常連さん
会議室デビュー日: 2003/04/06
投稿数: 42
投稿日時: 2003-04-15 18:09
こんにちは。
C++.NETのManaged C++について質問があります。
以下のようにiの値をConsole::WriteLine()で出力したいのですが、コンパイルエラー
が発生してしまいます。
なぜだか教えて頂けますでしょうか。
コード:
#include "stdafx.h"

#using <mscorlib.dll>

#include <tchar.h>

using namespace System;

// このアプリケーションのエントリ ポイントです。
int _tmain(void)
{
	int i = 0;

	Console::WriteLine("i = {0}", i);
	return 0;
}


よろしくお願い致します。
Qoo
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 121
投稿日時: 2003-04-15 18:36
こんにちは。

WriteLine()の引数に、書式指定を含んだ形式のもの
WriteLine( String format, params object[] args )
がないからコンパイラに怒られてるのでは?

恐らく意図されているのは、WriteLine()に iの値を適用した後の文字列を渡したい
のだろうと思いますけど。(^^;
Qoo
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 121
投稿日時: 2003-04-15 18:41
こんにちは。

ヘルプで見たら、書式指定を含んだ形式のものってありましたね。(^^;;;
すみません。

Console::WriteLine("i = {0}", i.ToString());
でどうでしょ?
MUSE
常連さん
会議室デビュー日: 2003/04/06
投稿数: 42
投稿日時: 2003-04-15 22:37
返信ありがとうございます。
確かにこの方法でもよいのですが、すみません、少し説明不足だったようです。
以下の二つのコードをみて下さい。

C#の場合
コード:
using System;

namespace CSConsoleApplication
{
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            int i = 16;

            Console.WriteLine("i = {0}", i);
        }
    }
}



Managed C++の場合
コード:
#include "stdafx.h"
#using <mscorlib.dll>
#include <tchar.h>
using namespace System;

int _tmain(void)
{
    int i = 16;

    Console::WriteLine("i = {0}", i);
    return 0;
}



C#だと
public static void WriteLine(string, object);

Managed C++
public: static void WriteLine(String*, Object*);

というオーバーロードを呼び出していると思うのですが、Managed C++のソースの
場合、

error C2665: 'System::Console::WriteLine' : 19 のオーバーロードは 2 番目
の引数を 'int' から要求の型に変換できません。(新しい機能 ; ヘルプを参照)

というエラーメッセージが出てしまいます。
第2パラメータの型の指定が誤っているようなのですが、何が誤りなのかよく分か
りません。

ご教授をお願いできますでしょうか?

よろしくお願いいたします。
TER
会議室デビュー日: 2003/04/15
投稿数: 5
お住まい・勤務地: 大阪
投稿日時: 2003-04-15 23:13
はじめまして。

Console::WriteLine("i = {0}", __box(i));

明示的にbox化すればいいのでは?

masa
常連さん
会議室デビュー日: 2003/04/16
投稿数: 38
投稿日時: 2003-04-16 06:52
はじめまして。

上記ののTERさんと同意見です。
私なりに考えることを、少し解説いたします。

書式フォーマットを行うために、
 void Console::WriteLine(String*, Object*)
という構文を使用しようとしています。

しかし、
 Console::WriteLine("i = {0}", i);
では、
 Console::WriteLine(String*, int)
と認識され、
 Console::WriteLine(String*, Object*)
とはなりません。

その理由は'i'がボックス化されていないからです。
ちなみに、ボックス化とは、__value クラスのオブジェクトからマネージドオブジェクト(System:bjectを継承しているオブジェクト)を作成することです。
なお、C++ のプリミティブ型(intなど)は __value クラスに対応しています。

よって、以下のコードでよろしいのではないかと思うのですが、いかがでしょうか?

 int i = 16;
 Object* obj = __box(i); // ボックス化
 Console::WriteLine("i = {0}", obj);

以上、よろしくお願いします。
Qoo
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 121
投稿日時: 2003-04-16 11:34
こんにちは。

勘違いした返答をしてしまい、すみません。m(_ _)m

ヘルプの方に、次のような記述がありました。
C++:マネージ拡張の使用 「5.2 ボックス化された __value クラス」より

メモ Visual C# とは異なり、パフォーマンス上の理由から、
ボックス化は C++ マネージ拡張では暗黙ではありません。
必要な場合は、値型を明示的にボックス化する必要があります。


このため、C#ではコンパイルが通るけど、C++ではコンパイルが通らない
ということのようですね。
MUSE
常連さん
会議室デビュー日: 2003/04/06
投稿数: 42
投稿日時: 2003-04-16 14:48
ありがとうございました。

> Console::WriteLine(String*, int)
>と認識され、
> Console::WriteLine(String*, Object*)
>とはなりません。

なるほど。よく分かりました。
また、

>メモ Visual C# とは異なり、パフォーマンス上の理由から、
>ボックス化は C++ マネージ拡張では暗黙ではありません。
>必要な場合は、値型を明示的にボックス化する必要があります。

というのも私がほしい回答でした。
暗黙ではボックス化はしないわけですね。

Qooさん、TERさん、masaさん、ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)