2016-12-10 7 views
3

私は恐ろしい質問だと恐れていますが...参照変数ではない代入を禁止する方法は?

誰かが、関数(またはメソッド)からの戻り値を強制的に内部の静的変数またはクラス/構造体は、参照変数にのみ割り当てられますか?

私は最小限の例で私が望むものを説明しようとします。内部静的変数への参照を返す関数wrapValue()と次のコードを、与えられ

int & wrapValue (int v0) 
{ 
    static int val; 

    return val = v0; 
} 

int main() 
{ 
    // how to permit this ... 
    int & v0 { wrapValue(0) }; 

    // ... but forbid this ... 
    int v1 { wrapValue(1) }; 

    int v2; 

    // ... and this ? 
    v2 = wrapValue(2); 
} 

v0の初期化を可能にする方法がある(静的変数にv0に結合)とv1の初期化と、(スタティック変数に境界線なし)(v1v2)を禁止しますか?

現在のC++標準では不可能なことがあれば、誰かが私に代わりの方法を提案することができます(あまりにも複雑ではありません:私はライブラリでそれを使いたいと思っています) ?

+0

あなたがしたいのはなぜ?彼らがあなたの戻り値で何をするかはあなたの発信者次第ですか? –

+0

おそらく、値をコピーしたり、移動したり構築したりしたくないのでしょうか?あるいは動かなかったのだろうか? – wally

+0

@AlanStokes - 問題は、ユーザが単純な(参照ではない)値で、私が開発したメソッド(argc/argvの値解析のオプションのクラス)によって返された値を入れた場合、次に、解析されます。たぶんそれは愚かな考えですが、ユーザーが '&'を覚えていればうまくいくようです。私は英語では悪いので、説明するのは難しいです...興味があれば(Stack Overflowのルールによれば正しいですか?)、私はgithubプロジェクトへのリンクを書くことができます。 – max66

答えて

4

このソリューションは、ややトリッキーですが、あなたが期待するとして、それは(私が思う)作品:

#include <iostream> 

struct int_wrapper { 
    int value; 
    int_wrapper &operator=(int value) { 
     this->value = value; 
     return *this; 
    } 
    operator int&() { 
     return value; 
    } 
    operator int() { 
     return value; 
    } 
}; 

int_wrapper& wrapValue (int v0) { 
    static int_wrapper val; 
    return val = v0; 
} 

int main() { 
    // how to permit this ... 
    int & v0 = wrapValue(0); 

    // ... but forbid this ... 
    //int v1 { wrapValue(1) }; // call ambigious 

    int v2; 
    (void)v0; 
    (void)v2; 

    // ... and this ? 
    //v2 = wrapValue(2); // call ambigious 
} 

[live demo]

+0

トリッキーだが使いやすく素敵です。私の本当の問題はテンプレートを含んでいますが、テンプレートラッパーで 'int_wrapper'を簡単に変更する必要があります。私は試してみるつもりですが、今は+1してください。 – max66

+0

@ max66なぜこのソリューションは、中括弧でイニシャライザを囲んで参照の初期化を禁止していますか? 'int&v0 {wrapValue(0)};'(値の場合とまったく同じですか?)一方、 'int&v0(wrapValue(0));'はあいまいさを引き起こさない...その解釈方法を知らない... –

+0

面白い;私もそうです(私はそれをどのように解釈するのか分かりません...)。私はあなたが質問を開く必要があると思います:) – max66

2

私が知っている限り、intはコピー可能なので、好きなだけコピーできます。これを防ぐことはできません。ただし、コピーできないラッパークラスを作成することもできます。

class NonCopyableInt 
{ 
    int val; 
public: 
    NonCopyableInt(int val) : val(val) {} 
    NonCopyableInt(NonCopyableInt&) = delete; 
    int& value() { return val; } 
    // todo: add some nice operators and functions such as assignment from int 
} 

NonCopyableInt& wrapValue (int v0) 
{ 
    static NonCopyableInt val; 
    return val = v0; 
} 

しかし、人々は常にvalue()から戻り値をコピーして、同じ問題を引き起こす可能性があります。そして、それは本当にclunkyとmehを感じる。

関連する問題