hageking
@hageking

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

C++のmapについて

Q&A

Closed

解決したいこと

C++でmapのValueのtypeをkeyごとに変更はできないんでしょうか?

自分で試したこと

source.cpp
#include <iostream>
#include <map>
#include <vector>
using namespace std;

int main()
{
    map<const char *, auto> data_map;
    vector<int> data_vector={3,8,96,6};
    data_map["1"] = "1";
    data_map["2"] = 2;
    data_map["3"] = data_vector;
    cout << data_map["3"][0];
    return 0;
}

error
./test.cpp:8:23: error: 'auto' not allowed in template argument
    map<const char *, auto> data_map;
                      ^~~~
1 error generated.

typeをautoにしましたがエラーが出てしまいます。
どうしたらValueのtypeをkeyごとに変更できますか?

0

3Answer

auto は初期化子から推論する形でコンパイル時になんらかの型に確定するような機能であって動的型の実現には使えません。

動的型が必要であれば抽象クラスを用いたクラス設計にするか std::variantstd::any などを用いてください。 ただ一般的には動的型は煩雑になりがちで正しく使うのが難しいです。

おそらくやろうとしていることをプログラムで表すとこんな雰囲気だと思います。 (C++17 を想定しています。)

#include <iostream>
#include <map>
#include <string>
#include <variant>
#include <vector>

// 型に対応して処理するクラス
struct visitor {
    // 基本的には何もしない
    template <class T>
    void operator()(const T&) {}
};

// std::vector<int> のときだけ特別扱いする特殊化
template <>
void visitor::operator()<std::vector<int>>(const std::vector<int>& x) {
    // 最初の要素を表示する
    std::cout << x[0] << std::endl;
}

int main(void) {
    std::map<std::string, std::variant<int, std::vector<int>, std::string>> data_map;
    std::vector<int> data_vector = {3, 8, 96, 6};
    data_map["1"] = "1";
    data_map["2"] = 2;
    data_map["3"] = data_vector;
    std::visit(visitor(), data_map["3"]);
}

ところで質問の主旨とは違うところですが、キーのほうも const char* はおそらく意図通りに動きません。 const char* はあくまでもポインタであり、ポインタの比較はポインタが指しているオブジェクトの「場所」で比較されてしまうからです。

文字列リテラルは同じ内容が統合されてもよい (されなくてもよい) ことになっているので配置についてなんらかの仮定をおいてはいけません。

#include <iostream>

int main(void) {
    // これは 0 のことも 1 のこともある
    std::cout << ("abc"=="abc") << std::endl;
}
3Like

Comments

  1. @hageking

    Questioner

    解決しました。
    回答してくれてくれてありがとうございます。

Comments

  1. @hageking

    Questioner

    回答してくれてありがとうございます。

Your answer might help someone💌