質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

923閲覧

std::common_typeの挙動に関して教えて下さい

wistaile

総合スコア24

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

0クリップ

投稿2021/09/07 11:32

以下の問題に直面したので、なぜこのような挙動になるのか、どうしたら解決できるか教えて下さい。

まず、以下のようなstd::pairと、const referenceをもつstd::pairがあります。

C++

1 using pair = std::pair<int, double>; 2 using pair_cc = std::pair<const int&, const double&>;

pairはpair_ccからコンストラクト可能です。

C++

1 const int i{}; 2 const double d{}; 3 pair_cc pcc{i, d}; 4 pair p1{pcc}; 5 pair p2{std::move(pcc)};

しかし、std::common_type_t<pair, pair_cc>を取得しようとすると、typeが存在しないとエラーが出ます。

C++

1 using type = std::common_type_t<pair, pair_cc>; 2 // no type named ‘type’ in ‘struct std::common_type<std::pair<int, double>, std::pair<const int&, const double&> >

明らかに共通の変換先が存在するのに、common_typeを取得できないのはなぜですか?
また、common_typeを取得できるようするためにはどうしたらいいですか?
ここによると、ユーザー定義の特殊化をすればいいようですが、プログラム定義型に依存していないのに特殊化してもいいのでしょうか。

どうかご教授ください。よろしくお願い申し上げます。

SaitoAtsushi👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

質問者が参考にしたとして挙げているページをよく見て頂ければわかりますが、共通型を決定するプロセスの内でこの場合に効いてくるのは

cpp

1decltype(false ? declval<D1>() : declval<D2>())

の部分です。 条件演算子で共通項を見つける工程と同じルールが適用されます。

そして条件演算子において共通項を見つける工程は複雑ではあるのですが、この場合においては与えられた二つの型が相互に変換できる場合は ill-formed であるという規定にひっかかります。

要するに pairpair_cc が相互に変換できることが失敗の原因です。 質問者がいう「common_type を取得できるようにするには」という要望は成り立ちません。 取得を試みた結果として存在しなかったから失敗したという状況なので。

投稿2021/09/07 13:31

SaitoAtsushi

総合スコア5466

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wistaile

2021/09/07 14:32

std::pair<const int&, double&>なら成功するのに、なぜだろうと思っていました。 やはり、三項演算子の結果型の曖昧さが原因のようですね。 ありがとうございます。
guest

0

明らかに共通の変換先が存在するのに、common_typeを取得できないのはなぜですか?

直接的には「そういうライブラリ仕様となっているから」が答えです。common_typeメタ関数は、任意の型の組から共通型を導出してくれる汎用部品ではありません。

common_typeメタ関数はC++11ライブラリの時刻関連機能(<chrono>ヘッダ)とともに導入されました。 例えば最初期の提案では、次のように概要説明されています。

Additionally, a minimal amount of general purpose infrastructure is proposed which will support both the interface and implementation of the clocks, time_points and durations proposed herein. It is expected that these general purpose facilities will also find utility in far ranging user applications as well.

  • common_type is a facility which is useful in specifying the type of the result of functions and operators which take a variety of types (e.g. "mixed mode" complex arithmetic).
  • [...]

外部QAサイトの質問と回答 What is the purpose of std::common_type?(英語) も参考にどうぞ。

投稿2021/09/07 13:43

yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wistaile

2021/09/07 14:33

読んでみました。 魔法のような名前をしているのに全然融通がきかないのが困ります。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問