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

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

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

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

コンパイルエラー

コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。

C++

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

Q&A

解決済

1回答

1051閲覧

VisualStudioC++:template<template>におけるconceptのコンパイルエラーの原因が知りたい

fluid_love

総合スコア21

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

コンパイルエラー

コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。

C++

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

1グッド

3クリップ

投稿2021/06/09 12:21

環境

  • Microsoft Visual Studio Community 2019
  • Version 16.10.0
  • c++latest

問題

次のコードは上の環境でコンパイルエラーです.

質問:コンパイラのバグなのか,文法のエラーなのか,それとも別の原因なのかが知りたい

#include <iostream> enum class Color { RED }; template<typename T, template <auto,typename> typename U> concept AA = true; template<typename T, template <typename> typename U> concept BB = true; template<typename T, template <auto> typename U> concept CC = true; template<Color, std::integral T> struct A {}; template<std::integral T> struct B {}; template<Color> struct C {}; template<AA<A> T> void aa(T v) { std::cout << typeid(v).name(); } template<BB<B> T> void bb(T v) { std::cout << typeid(v).name(); } template<CC<C> T> void cc(T v) { std::cout << typeid(v).name(); } int main() { A<Color::RED,int> a; //aa(a);//error B<int> b; bb(b);//ok C<Color::RED> c; cc(c);//ok }
C2672 'aa': 一致するオーバーロードされた関数が見つかりませんでした。 C7602 'aa': 関連する制約が満たされていません

詳細

auto typename
typename
auto
の三種類のconceptを作成します.

template<typename T, template <auto,typename> typename U> concept AA = true; template<typename T, template <typename> typename U> concept BB = true; template<typename T, template <auto> typename U> concept CC = true;

それらを使って関数に渡される型を制約します.
-conceptAA conceptBB conceptCCそれぞれ作成します.

template<AA<A> T> void aa(T v) { std::cout << typeid(v).name(); } template<BB<B> T> void bb(T v) { std::cout << typeid(v).name(); } template<CC<C> T> void cc(T v) { std::cout << typeid(v).name(); }

テスト用のクラスをそれぞれ作成して,

template<Color, std::integral T> struct A {}; template<std::integral T> struct B {}; template<Color> struct C {};

main関数で呼びます.

int main() { A<Color::RED,int> a; //aa(a);//error B<int> b; bb(b);//ok C<Color::RED> c; cc(c);//ok }

関数aa以外は問題なく動作します.

別のコンパイラで確認したところ動作するようです.


別のコンパイラ

  • gcc11.1.0->ok

wandboxで確認

  • clang13.0.0->ok

wandboxで確認

ttact👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

私が理解している限りでは、質問者の提示しているコードは正しい (コンパイルが通るべき) です。 コンパイラのバグだと考えてよいと思います。

発生条件を切り分けるため AA をクラステンプレートにして MSVC で試してみてもエラーになりました。 AU がマッチしないという意味のエラーメッセージが出ます。

#include <iostream> #include <type_traits> template<template <auto, typename> typename U> class AA : public std::true_type {}; // 以下のいずれかなら通る // template<template <int, typename> typename U> class AA : public std::true_type {}; // template<template <auto, std::integral> typename U> class AA : public std::true_type {}; template<int, std::integral T> struct A {}; int main() { std::cout << AA<A>::value << std::endl; }

autotypename とだけ書いている引数のどちらかをより具体的にすると通ることが確認できるので個別には推論できていると思われるのですが合わさると駄目なようです。

  • 型引数に auto が含まれる
  • コンセプトで制約されている型を (requires で制約されていない) typename で受け取る

の両方をそれぞれ一つ以上含むような形でテンプレートを受け取るというのが問題の発生条件だと考えられます。

投稿2021/06/10 19:51

SaitoAtsushi

総合スコア5446

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

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

fluid_love

2021/06/11 05:50

ありがとうございます! VisualStudioのバグ報告をするところがあるようなので、同様のバグが報告されていないか確認してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問