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

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

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

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

3675閲覧

異なる型同士を格納する配列および,順番通りに処理を実行するプログラム

jonjon

総合スコア5

C++

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/03/10 15:54

編集2020/03/10 20:20

前提・実現したいこと

異なる型同士を格納することができる配列を定義し,あるデータを入力すると,定義した順番通りに処理を実行するクラスを作成したいです.
(「PyTorch」の「nn.Sequential」「transforms」みたいなものを作りたいです.)

例えば,A〜Cの関数の中から好きなだけ選択し,データDに対して「関数A→関数B→関数A」を実行することを試みます.
この順番に処理を実行する配列Eを定義し,別のソースファイルSに引数として与えます.
Sは,データD,配列Eの情報をもとに,データDを「関数A→関数B→関数A」という流れに沿って実行します.

そこで,以下のコードを書きましたが,異なる型同士を格納する配列を別の関数に渡した途端動かなくなります.
クラスの継承元が同じであれば,ソースコードみたいに型が違っていても親クラスのポインタを利用することで同時に格納できると聞きました.
しかし,上記のエラーが発生して上手く動きませんでした.

どなたかこの原因を教えてくださると助かります.
また,解決策があれば教えていただけると幸いです.

<必須条件>
・「main.cpp」にて,「異なる型同士を格納する配列」と「処理の順番」を定義する.(下記のコードみたいに簡単に書けるようにしたい.)
・「active.cpp」にて,定義した順番通りに処理を実行する.
・「main.cpp」にて定義した「異なる型同士を格納する配列」は,関数の引数を利用して「active.cpp」に渡す.
・「differents.hpp」にて,定義した順番通りに処理を実行するプログラムを実装する.
・プログラミング言語:C++

発生している問題・エラーメッセージ

コンパイルしようとすると,「関数が見つからない」というエラーが発生します.

$ g++ main.cpp active.cpp In file included from main.cpp:2:0: differents.hpp: In function ‘int differents::forward(std::vector<differents::Compose*>&, int, int)’: differents.hpp:11:30: error: request for member ‘forward’ in ‘different’, which is of pointer type ‘differents::Compose*’ (maybe you meant to use ‘->’ ?) return different.forward(differents::forward(different_, data, count_next)); In file included from active.cpp:3:0: differents.hpp: In function ‘int differents::forward(std::vector<differents::Compose*>&, int, int)’: differents.hpp:11:30: error: request for member ‘forward’ in ‘different’, which is of pointer type ‘differents::Compose*’ (maybe you meant to use ‘->’ ?) return different.forward(differents::forward(different_, data, count_next));

該当のソースコード

・main.cpp

C++

1#include <vector> 2#include "differents.hpp" 3 4void active(std::vector<differents::Compose*> &different); // active.cppにて実装 5 6int main(void){ 7 std::vector<differents::Compose*> different{ 8 (differents::Compose*)new differents::process1(2), 9 (differents::Compose*)new differents::process2(3), 10 (differents::Compose*)new differents::process1(4) 11 }; 12 active(different); 13 return 0; 14}

 
・active.cpp

C++

1#include <iostream> 2#include <vector> 3#include "differents.hpp" 4 5void active(std::vector<differents::Compose*> &different){ 6 int ans = differents::forward(/*different_=*/different, /*data=*/5, /*count=*/different.size()); 7 std::cout << ans << std::endl; // (4 + (3 + (2 + 5 + 1) + 2) + 1) = 18 8}

 
・differents.hpp

C++

1#include <vector> 2 3namespace differents{ 4 5 class Compose{}; 6 7 int forward(std::vector<differents::Compose*> &different_, const int data, const int count){ 8 int count_next = count - 1; 9 auto different = different_.at(count_next); 10 if (count_next >= 0){ 11 return different.forward(differents::forward(different_, data, count_next)); 12 } 13 return data; 14 } 15 16 class process1 : differents::Compose{ 17 private: 18 int x; 19 public: 20 process1(const int x_){ 21 x = x_; 22 } 23 int forward(const int y){ 24 return x + y + 1; 25 } 26 }; 27 28 class process2 : differents::Compose{ 29 private: 30 int x; 31 public: 32 process2(const int x_){ 33 x = x_; 34 } 35 int forward(const int y){ 36 return x + y + 2; 37 } 38 }; 39 40 class process3 : differents::Compose{ 41 private: 42 int x; 43 public: 44 process3(const int x_){ 45 x = x_; 46 } 47 int forward(const int y){ 48 return x + y + 5; 49 } 50 }; 51 52} 53

試したこと

以下のように実行したらエラーが出ました.

$ g++ main.cpp active.cpp In file included from main.cpp:2:0: differents.hpp: In function ‘int differents::forward(std::vector<differents::Compose*>&, int, int)’: differents.hpp:11:30: error: request for member ‘forward’ in ‘different’, which is of pointer type ‘differents::Compose*’ (maybe you meant to use ‘->’ ?) return different.forward(differents::forward(different_, data, count_next)); In file included from active.cpp:3:0: differents.hpp: In function ‘int differents::forward(std::vector<differents::Compose*>&, int, int)’: differents.hpp:11:30: error: request for member ‘forward’ in ‘different’, which is of pointer type ‘differents::Compose*’ (maybe you meant to use ‘->’ ?) return different.forward(differents::forward(different_, data, count_next));

「*」を「->」に変更してもエラーが出ました.

$ g++ main.cpp active.cpp In file included from main.cpp:2:0: differents.hpp: In function ‘int differents::forward(std::vector<differents::Compose*>&, int, int)’: differents.hpp:11:31: error: ‘class differents::Compose’ has no member named ‘forward’ return different->forward(differents::forward(different_, data, count_next)); ^~~~~~~ In file included from active.cpp:3:0: differents.hpp: In function ‘int differents::forward(std::vector<differents::Compose*>&, int, int)’: differents.hpp:11:31: error: ‘class differents::Compose’ has no member named ‘forward’ return different->forward(differents::forward(different_, data, count_next));

補足情報(FW/ツールのバージョンなど)

C++14

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

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

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

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

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

jimbe

2020/03/10 19:34

C と C++ は別モノですので, タグを外しておいて頂けますか.
jonjon

2020/03/10 20:16

了解しました.
jimbe

2020/03/11 03:48

ありがとうございます.
guest

回答2

0

ベストアンサー

  • 基底クラスのポインタから基底クラスにないメンバ関数は呼び出す事ができません。
  • 仮想関数にしないと意図通りには動かないでしょう。

c++

1struct Compose{ 2 virtual int forward(const int y) = 0; 3 virtual ~Compose() = 0; 4}; 5 6Compose::~Compose(){} 7 8class process1 : Compose{ 9private: 10 int x; 11public: 12 process1(const int x) : x(x) {} 13 ~process1(){} 14 int forward(int y) override { 15 return x + y + 1; 16 } 17};

ラムダ式で充分かと

c++

1#include <functional> 2#include <vector> 3#include <numeric> 4 5using Func1 = std::function<int(int)>; 6 7Func1 process1(int x){ return [x](int y){return x + y + 1;}; } 8Func1 process2(int x){ return [x](int y){return x + y + 2;}; } 9Func1 process3(int x){ return [x](int y){return x + y + 5;}; } 10 11int main() 12{ 13 std::vector<Func1> ary; 14 ary.push_back(process1(2)); 15 ary.push_back(process2(3)); 16 ary.push_back(process1(4)); 17 // std::cout << ary[0](ary[1](ary[2](5))); 18 std::cout << std::accumulate(ary.rbegin(), ary.rend(), 5, 19 [](int x, Func1 f){return f(x);}); 20}

投稿2020/03/10 17:23

編集2020/03/10 17:43
asm

総合スコア15147

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

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

jonjon

2020/03/10 20:15

回答ありがとうございます. 実際に実行してみたところ上手く動作しました! 同じ関数を親クラスにも設置し,親クラスには「virtual」を,子クラスには「override」をつけると良いのですね. ありがとうございました!
guest

0

変数 different はそれが Compose 型のオブジェクトを指すポインタであることしかコンパイルは知りません。 Compose 型は forward というメンバ関数を持っていないのでエラーになるという単純な理屈です。

differents::Compose を継承したクラスみっつはいずれもメンバ関数 forward を持っていますが、この状態ではたまたま同じ名前を持つだけの別物であって関連性がないのです。

Compose が「仮想関数」として forward を持ち、それをオーバーライド (override) する形で定義する必要があります。

仮想関数について調べてみてください。

投稿2020/03/10 17:18

SaitoAtsushi

総合スコア5437

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

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

jonjon

2020/03/10 20:12

なるほど...勉強になりました. 仮想関数について勉強してみます. ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問