49646


関数テンプレートと関数のオーバーライドの違いを教えてくれますでしょうか？  
また内部処理の違いなど知りたいです、

[code]

    template<typename type>
    void view(list<type> &lst)
    {
        int i = 0;
        for (typename list<type>::iterator itr = lst.begin(); itr != lst.end(); itr++, i++) {
            cout << i << ": " << *itr << "\n";
        }
        cout << "\n\n";
    }
    
    
    /*選択した要素数を指定の数字に変更*/
    template<typename type,typename typeb>
    void number_set(list<type> &lst, int &idx,typeb &n)
    {
    
        int i = 0;
        typename list<type>::iterator it = lst.begin();
        while (it != lst.end() && i != idx )
        {   
            i++;
            it++;
        }
    
        for (typename list<type>::iterator itr = lst.begin(); itr != lst.end(); itr++) {
            if (itr == it) {
                *itr = n;
            }
        }
    
        view(lst);
    }
    
    void number(list<int> &lst, int idx, int &n)
    {
        cout << "int版\n";
    
        int i = 0;
        list<int>::iterator it = lst.begin();
        while (it != lst.end() && i != idx)
        {
            i++;
            it++;
        }
    
        for (list<int>::iterator itr = lst.begin(); itr != lst.end(); itr++)
        {
            if (itr == it)
            {
                *itr = n;
            }
        }
    
        view(lst);
    }
    
    void number(list<double> &lst, int idx, double &n)
    {
        cout << "double版\n";
        int i = 0;
        list<double>::iterator it = lst.begin();
        while (it != lst.end() && i != idx)
        {
            i++;
            it++;
        }
    
        for (list<double>::iterator itr = lst.begin(); itr != lst.end(); itr++)
        {
            if (itr == it)
            {
                *itr = n;
            }
        }
    
        view(lst);
    }
    
    int main() {
    
        int p = 0;
        //double p = 0.0;
        //int n = 0;
        double n = 0.0;
    
        list<double> lst(10,1.5);
        //list<int> lst(10, 1);
    
        view(lst);
        cout << "添え字を選択してください:";
        cin >> p;
        cout << "値:";
        cin >> n;
    
        //number_set(lst,p,n);
        number(lst, p, n);
    
    
    
        _getch();
        return 0;
    }
    
[/code]


CC BY-SA 4.0
2018-10-18T13:39:21.043
49418
2018-10-31T08:59:40.317
2018-10-31T08:59:40.317
5008
question
c++
関数テンプレートと関数のオーバーライドの違いが知りたい


なんか回答つかないっすけど１つめの回答は

  * ほぼ同じことができる
  * なのでオーバーロードを `template` にできるならそっちのほうが良い

* * *
[code]

    void func(int x, int y) { ... }
    void func(double x, double y) { ... }
    
[/code]

が **全く同じこと**
を内部でしているのであれば「同じコードを２回書いている」ってことで、プログラマの理想の一つ「怠惰」から見てよろしくないってことになります。バグが見つかったら２つとも直す必要がありますし、それを人手で行うと漏れが出ます。全く同じことを繰り返さないようにするための
`template` ですから

[code]

    template<typename T>
    void func(T x, T y) { ... }
    
[/code]

とするほうが望ましいわけです。そういう意味でオーバーロードを `template`
化できるのであれば、すべきであろう、というのが１つ目の答えとなりそうです。

ただし、できるのであれば、という但し書きが付きます。よくあるのはそこがボトルネックになっていて１クロックでも速くしたいとか、ここで精度落ちしてるから特定の型に特化したアルゴリズムを使う必要があるとか。そういう場合には
`template` より「普通の関数」を複数実装するほうがわかりやすかったりします。

`template` を多用しすぎるとコンパイル・リンク時間が長くなるとかもありますしね。

* * *

２つ目、違いは？という質問への答えは

  * 「通常の関数」があって、オーバーロード規則に従い fit するものと
  * 「関数テンプレート」があって fit するものと、

両方があるときは前者が使われます。コンパイル時だけでなくリンク時にも処理が行われ

[template 関数で同じ関数が複数定義される場合](https://ja.stackoverflow.com/questions/14219/)  
の答えの後半の通り、

  * 非 `template` な通常関数は STRONG symbol となる
  * `template` を具現化した関数は weak symbol となる
  * weak が複数個あって STORNG がない場合は weak が１つだけ残る
  * weak と STRONG が両方あると STRONG が使われる (weak は捨てられる)

関数テンプレートの具現化と通常の関数が両方あるときは、通常の関数が残ります。  
(この辺が悩ましいコードはたいてい ODR 違反だったりする)

* * *

直接関係ないけど気になったこと。

用語「テンプレート関数」はおかしいです。 `template` は文字通り [鋳型] です。 `template`
な関数があるわけではありません。ここをはき違えるとこの先の理解が遅くなります。

「関数テンプレート」なら日本語として正確です。関数テンプレートは、具現化して初めて関数になります。同様「テンプレートクラス」はおかしくて、「クラステンプレート」なら正確です。クラステンプレートを具現化して初めてクラスになります。

「まだ関数じゃない」 (P.K.Dick) 。些細な違い？いや、本質だとオイラは思う。


CC BY-SA 4.0
2018-10-25T07:51:45.603
49646
2018-10-26T00:27:45.343
2018-10-26T00:27:45.343
8589
8589
49418
answer