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

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

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

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

Q&A

解決済

1回答

348閲覧

<type_traits> enable_if_t型の bool 部分を関数化したい

m4697859930

総合スコア16

C++

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

1グッド

0クリップ

投稿2018/12/30 05:19

forward

以前の質問「<cstdint> int(NN)_t型のオーバーロードにおける重複をなくしたい」は2名の方からのコメントで無事解決に至りました。しかし、コードを少しいじっている中で疑問点が生じました。その内容は以前の質問とあまりかかわりのない部分でしたので、新しく質問させていただくことにしました。

code

C++

1 2// before 3 4#include <iostream> 5#include <cstdio> 6#include <cstdint> 7#include <cinttypes> 8 9namespace { 10 struct in 11 { 12 template<typename T> 13 auto operator >>(T& val) -> std::enable_if_t<std::is_unsigned_v<T> && sizeof(T) == sizeof(uint64_t), in&> 14 { 15 std::scanf("%" SCNu64, &val); return *this; 16 } 17 }; 18} 19

C++

1 2// after 3 4#include <iostream> 5#include <cstdio> 6#include <cstdint> 7#include <cinttypes> 8 9namespace { 10 struct in 11 { 12 template<typename T> 13 auto operator >>(T& val) -> std::enable_if_t<condetion(T, uint64_t), in&> 14 { 15 std::scanf("%" SCNu64, &val); return *this; 16 } 17 18private: 19 bool condition(typename T, typename U) { 20 return std::is_unsigned_v<T> && sizeof(T) == sizeof(U); 21 } 22 }; 23} 24

error

Wandbox (C++ gcc HEAD 9.0.0 20181227 (experimental)) で返ってきたエラーです。

prog.cc:21:48: error: there are no arguments to 'condition' that depend on a template parameter, so a declaration of 'condition' must be available [-fpermissive] 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^~~~~~~~~ prog.cc:21:48: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated) prog.cc:21:75: error: template argument 1 is invalid 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^ prog.cc:21:48: error: there are no arguments to 'condition' that depend on a template parameter, so a declaration of 'condition' must be available [-fpermissive] 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^~~~~~~~~ prog.cc:21:75: error: template argument 1 is invalid 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^ prog.cc:21:48: error: there are no arguments to 'condition' that depend on a template parameter, so a declaration of 'condition' must be available [-fpermissive] 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^~~~~~~~~ prog.cc:21:75: error: template argument 1 is invalid 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^ prog.cc:21:48: error: there are no arguments to 'condition' that depend on a template parameter, so a declaration of 'condition' must be available [-fpermissive] 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^~~~~~~~~ prog.cc:21:75: error: template argument 1 is invalid 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^ prog.cc:21:48: error: there are no arguments to 'condition' that depend on a template parameter, so a declaration of 'condition' must be available [-fpermissive] 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^~~~~~~~~ prog.cc:21:75: error: template argument 1 is invalid 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^ prog.cc:21:48: error: there are no arguments to 'condition' that depend on a template parameter, so a declaration of 'condition' must be available [-fpermissive] 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^~~~~~~~~ prog.cc:21:75: error: template argument 1 is invalid 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^ prog.cc:21:31: error: invalid use of template-name 'std::enable_if_t' without an argument list 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^~~ In file included from /opt/wandbox/gcc-head/include/c++/9.0.0/bits/move.h:55, from /opt/wandbox/gcc-head/include/c++/9.0.0/bits/nested_exception.h:40, from /opt/wandbox/gcc-head/include/c++/9.0.0/exception:144, from /opt/wandbox/gcc-head/include/c++/9.0.0/ios:39, from /opt/wandbox/gcc-head/include/c++/9.0.0/ostream:38, from /opt/wandbox/gcc-head/include/c++/9.0.0/iostream:39, from prog.cc:1: /opt/wandbox/gcc-head/include/c++/9.0.0/type_traits:2382:61: note: 'template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type' declared here 2382 | using enable_if_t = typename enable_if<_Cond, _Tp>::type; | ^ prog.cc:21:47: error: expected initializer before '<' token 21 | auto operator >>(T& val) -> std::enable_if_t<condition(T, uint64_t), in&> | ^ prog.cc:26:27: error: expected nested-name-specifier before 'T' 26 | bool condition(typename T, typename U) { | ^ prog.cc:26:39: error: expected nested-name-specifier before 'U' 26 | bool condition(typename T, typename U) { | ^ prog.cc: In member function 'bool {anonymous}::in::condition(int, int)': prog.cc:27:16: error: type/value mismatch at argument 1 in template parameter list for 'template<class _Tp> constexpr const bool std::is_unsigned_v<_Tp>' 27 | return std::is_unsigned_v<T> && sizeof(T) == sizeof(U); | ^~~~~~~~~~~~~~~~ prog.cc:27:16: note: expected a type, got 'T' prog.cc: In function 'int main()': prog.cc:33:22: error: no match for 'operator>>' (operand types are '{anonymous}::in' and 'uint64_t' {aka 'long unsigned int'}) 33 | uint64_t i; in() >> i; std::cout<<i<<"\n"; | ~~~~ ^~ ~ | | | | | uint64_t {aka long unsigned int} | {anonymous}::in

problem

C++

1 2int main(){ 3 uint64_t i; in() >> i; std::cout << i << "\n"; 4 return 0; 5} 6

抜粋前のコードは int(NN)_t型全て対してオペレータを定義しているため、コード長を短くしようと
std::enable_if_t<bool Condition, class T = void> (std::enable_if<bool Condition, class T = void>::type)
の bool 部分を関数化しようとしたのです。しかし、上記のコードを加えて実行した際にエラーが発生してしまいました。関数化する前のコードはエラーなく動いてくれました。どうしてこのようなエラーが起こるのか、コードをどう直せばよいのかご教示いただけると幸いです。

※ エラーが何を指しているのかも google先生に頼ったもののあまり理解できていません。

bochan2👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

まず、基本的なこととして、方やcondetion、方やcondition
スペルが違います(転記ミス?)。

それ以外にも複数の誤りがあるので、それぞれについて指摘します。

  • 関数を呼び出す際は、それ以前に関数を定義するかプロトタイプ宣言が必要です。ご質問のコードでいえば、condition関数はoperator >>関数よりも前に書かなければいけません。

  • 関数の引数として型を渡すことはできません。関数テンプレートにしましょう。

  • テンプレート引数にはコンパイル時に確定する値を渡さなければいけません。関数を利用する場合はconstexprを付ける必要があります。また、メンバ関数の場合はstaticも付ける必要があります。

それらを踏まえてご質問のコードを修正すると、こんな感じになります。

c++

1struct in 2{ 3private: 4 template <typename T, typename U> 5 static constexpr bool condition() 6 { 7 return std::is_unsigned_v<T> && sizeof(T) == sizeof(U); 8 } 9 10public: 11 template<typename T> 12 auto operator >>(T& val) -> std::enable_if_t<condition<T, uint64_t>(), in&> 13 { 14 std::scanf("%" SCNu64, &val); return *this; 15 } 16};

投稿2018/12/30 09:09

catsforepaw

総合スコア5938

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

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

m4697859930

2018/12/30 10:37

回答ありがとうございます。腑に落ちなかった部分がすっきりしました。static constexpr の部分は知らなかったので、書籍やサイトなどで調べていきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問