21635


first class
の条件は[Wikipedia](https://ja.wikipedia.org/wiki/%E7%AC%AC%E4%B8%80%E7%B4%9A%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88)によると

  * 無名のリテラルとして表現可能である。
  * 変数に格納可能である。
  * データ構造に格納可能である。
  * それ自体が独自に存在できる（名前とは独立している）。
  * 他のものとの等値性の比較が可能である。
  * プロシージャや関数のパラメータとして渡すことができる。
  * プロシージャや関数の戻り値として返すことができる。
  * 実行時に構築可能である。
  * 表示可能である。
  * 読み込むことができる。
  * 分散したプロセス間で転送することができる。
  * 実行中のプロセスの外に保存することができる。

だそうですが、c++の場合は

  * 無名のリテラルとして表現可能である。 : lambdaを使えば可能
  * 変数に格納可能である。: funtion objectが存在
  * それ自体が独自に存在できる（名前とは独立している）。: 関数literalの条件とさほど変わらない条件だと考えます。
  * 他のものとの等値性の比較が可能である。: function objectの比較を考えるのなら、一応可能だと言っていいと思います。しかし、関数をデータ構造そのものとして考える場合は無理でしょう。
  * プロシージャや関数のパラメータとして渡すことができる。: 可能
  * プロシージャや関数の戻り値として返すことができる。: 可能

はだいたい満足するのではないか、と思います。上記により、第一級関数を扱える場合の嬉しいものとしてよく言われるclosureみたいのなら、c++でも実装可能になります。

では残った条件として：

  * 表示可能である。: 曖昧な言葉ですが、データ構造の表示を意味しているのなら、できないでしょう。そもそもruntimeで関数のデータ構造をいじったり見たりすることはc++ではできませんので。
  * 読み込むことができる。: これもまた曖昧ですが、上記と同じようなことだとおもいます。
  * 分散したプロセス間で転送することができる。
  * データ構造に格納可能である。：これは上記と合わせてhomoiconityについて述べているようですが、曖昧です。しかし、homoiconityが満足されれば一応、これは満足できるものです。
  * 実行時に構築可能である。
  * 実行中のプロセスの外に保存することができる。

がありますが、上記は大体、関数をruntimeで生成できないこと、つまり関数がデータ構造として扱われないことによるものです。しかし、他の言語で関数をruntimeで生成できるからと言って、特にc++の使い方とさほど変わらないような気がします。あるとしたらevalみたいな関数が実行時に柔軟に存在できるぐらいではないでしょうか。runtimeで関数が生成できるとどのような使い方ができますか？


CC BY-SA 3.0
2016-02-02T05:47:14.267
21612
2016-02-03T01:20:14.447
2016-02-02T06:12:51.773
8000
10856
question
c++
第一級関数の条件でruntimeで生成できることは何処に使える条件ですか？


例えば何らかのリスト・データセットをフィルターする場合、フィルター条件はユーザー選択など動的に決定される場合があります。このような場合に関数をruntimeに生成できる言語では、条件に基づいてフィルター関数を生成し適用できます。  
関数をruntimeに生成できないC++言語では、フィルター条件と照らし合わせながら比較を行う関数を用意することになるのではないでしょうか。

* * *

h2so5さんの回答にもやっとしていました。回答にある`func`は見かけ上はシンプルですが、内部では

[code]

    class greater {
        int _base;
    public:
        greater(int base) :_base(base) {}
        bool validate(int target) {
            return _base < target;
        }
    };
    
[/code]

と同様な動作をするクラスを事前に用意しておき、実行時にインスタンス生成しているに過ぎません。これをもって「関数をruntimeに生成」と呼べるかどうか、私には判断できません。それに対して例えばC#言語では

[code]

    using System;
    using System.Linq;
    using System.Linq.Expressions;
    
    class Program {
        static void Main(string[] args) {
            var num = int.Parse(Console.ReadLine());
    
            var param = Expression.Parameter(typeof(int));
            var lambda = Expression.Lambda<Func<int, bool>>(Expression.GreaterThan(param, Expression.Constant(num)), param);
            var func = lambda.Compile();
    
            int[] numbers = { 1, 3, -6, 7, 8, -4, -5, 7, -8 };
            foreach (var it in numbers.Where(func))
                Console.WriteLine(it);
        }
    }
    
[/code]

とすることができ、これについては例えば入力値が`5`であれば

[code]

    bool validate(int target) {
        return 5 < target;
    }
    
[/code]

という関数をruntimeに生成しています。  
この辺り、unaristさんの説明がしっくりきました。


CC BY-SA 3.0
2016-02-02T06:22:46.097
21614
2016-02-03T01:20:14.447
2016-02-03T01:20:14.447
4236
4236
21612
answer


C++の関数オブジェクトは実質的に第一級関数ですので、C++で第一級関数が扱えないという前提がそもそも間違っています。

関数オブジェクトを利用すれば、C++でも関数を実行時に生成することができます。

例えば以下のコードは、実行時に与えられた数値より大きい数値だけを配列の中から表示するものですが、`func`という比較関数は実行時に構築されています。

[code]

    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    
    int main() {
        int num;
        cin >> num;
    
        auto func = bind2nd(greater<int>(), num);
    
        int numbers[] = { 1, 3, -6, 7, 8, -4, -5, 7, -8 };
        for (auto it = begin(numbers); (it = find_if(it, end(numbers), func)) != end(numbers); ++it) {
            cout << *it << endl;
        }
    
        return 0;
    }
    
[/code]


CC BY-SA 3.0
2016-02-02T12:36:46.740
21633
2016-02-02T12:42:38.603
2016-02-02T12:42:38.603
3639
3639
21612
answer


closureみたいなものなら実装可能というか、C++11の関数オブジェクトはclosureと言えるでしょう。そしてclosureにclosureや値をキャプチャできる以上、関数オブジェクトは動的に構築可能と言えます。組み込み演算子やステートメントをそのままはめ込むことはできないものの、それも関数にしておけばいいですし。

言い換えると、closureの利点がほぼそのまま、関数を動的に構築できることの利点になると思います。

一方、ネイティブコード生成のことを指すのであれば、確かにC++にその機能はないでしょう。この場合の利点としては、前述の「関数オブジェクトの組み合わせ」に比べて高速に動作する可能性があります。C#だとシリアライザを動的に生成するときに動的コード生成が用いられたりしますね。


CC BY-SA 3.0
2016-02-02T15:24:22.180
21635
2016-02-02T15:24:22.180
8000
21612
answer