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

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

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

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

Q&A

解決済

2回答

670閲覧

powやsinなどの引数に入れることができる自作classの作り方を知りたい

fdaskjlfda

総合スコア40

C++

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

0グッド

1クリップ

投稿2022/04/04 15:01

編集2022/04/04 15:02

環境

c++17
(必要であれば、c++20に変更可能)

やりたいこと

c++

1class CustomInt { 2public: 3 CustomInt(int rhs) : value(rhs) {} 4 explicit operator int() const noexcept { return value; }; 5private: 6 int value; 7} 8std::ostream& operator<<(std::ostream& lhs, const CustomInt& rhs) 9{ 10 lhs << static_cast<int>(rhs); 11 return lhs; 12} 13 14int main() { 15 // 1 16 CustomInt hoge = {0}; 17 std::cout << hoge << std::endl; 18 hoge = 20; 19 std::cout << std::pow(static_cast<int>(hoge), 2) << std::endl; 20 21 // 2 22 std::cout << std::pow(hoge, 2) << std::endl; 23} 24

現在のコードだと、1の部分は問題なく実行できますが、2のコードは下のようなコンパイルエラーが出ます。

no matching function for call to 'pow(CustomInt&, int)

hogeというCustomIntのインスタンスが、あたかもint型のように振る舞うためにはどうoperatorなどを設定すればよいのでしょうか?

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

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

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

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

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

guest

回答2

0

あたかもint型のように振る舞うためには

operator int()explicit を消せばそのようになります。

しかし std::pow() には int 引数のものはないので、依然としてコンパイルはできないかもしれません。その場合は operator double() を足します。

投稿2022/04/04 15:31

編集2022/04/04 15:43
int32_t

総合スコア20850

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

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

fdaskjlfda

2022/04/05 01:23

わかりました!ありがとうございます!
guest

0

ベストアンサー

operator double()足せばいいというのはまあそうといえばそうなのですが、explicitじゃない型変換演算子を定義するのも正直どうかと思うので代案です。CPOを作ってみます。

cpp

1#include <iostream> 2#include <cmath> 3#include <concepts> 4namespace foo { 5class CustomInt { 6public: 7 CustomInt(int rhs) : value(rhs) {} 8 explicit operator int() const noexcept { return value; }; 9 template<std::integral T> 10 auto pow(T y) { return std::pow(this->value, y); } 11private: 12 int value; 13}; 14std::ostream& operator<<(std::ostream& lhs, const CustomInt& rhs) 15{ 16 lhs << static_cast<int>(rhs); 17 return lhs; 18} 19inline namespace cpo { 20 namespace detail{ 21 template <class T, class U> 22 concept has_pow_1 = requires (T x, U y) { 23 std::integral<U>; 24 {x.pow(y)} -> std::floating_point; 25 }; 26 template <class T, class U> 27 concept has_pow_2 = requires (T x, U y) { 28 std::floating_point<U>; 29 {x.pow(y)} -> std::same_as<U>; 30 }; 31 } 32 template <class T, class U> 33 concept has_pow = detail::has_pow_1<T, U> || detail::has_pow_2<T, U>; 34 struct pow_t { 35 template<std::floating_point T> 36 T operator()(T x, T y) const { return std::pow(x, y); } 37 template<std::integral T1, std::integral T2> 38 auto operator()(T1 x, T2 y) const { return std::pow(x, y); } 39 template<class T, class U> requires has_pow<T, U> 40 auto operator()(T x, U y) const { return x.pow(y); } 41 }; 42 inline constexpr pow_t pow{}; 43} 44} 45int main() { 46 // 1 47 foo::CustomInt hoge = {0}; 48 std::cout << hoge << std::endl; 49 hoge = 20; 50 std::cout << foo::pow(static_cast<int>(hoge), 2) << std::endl; 51 52 // 2 53 std::cout << foo::pow(hoge, 2) << std::endl; 54}

https://wandbox.org/permlink/mMZyvzq64bdhQogj

ref:

投稿2022/04/04 16:29

yumetodo

総合スコア5850

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

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

fdaskjlfda

2022/04/05 01:23

わかりました!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問