2013-05-16 11 views
22

考えてみましょう:C++ 11オペレーター ""

struct str {}; 

str operator"" _X(long double d) { 
    return str(); 
} 

これはウォールのstd = C++ 11

4.7.2 ++グラムと罰金が、今、私は、二重を与えた場合にコンパイル:

str operator"" _X(double d) { 
    return str(); 
} 

は、私は、次のエラーメッセージが出ます: main.cppには| 3 |エラー: 'STR演算子 "" _X(ダブル)' は無効な引数のリストを持っている

問題は何ですか?これは「組み込みのリテラルサフィックスの意味を再定義することはできません」(Stroustrup FAQ)と関係がありますか? 回避策について考えてもよろしいですか?

答えて

31

What is the problem?

問題は、規格がそれを禁じていることです。ユーザ定義リテラルのC++ 11標準の段落13.5.8./3パー:次は正常に動作しますので、回避策に関する

The declaration of a literal operator shall have a parameter-declaration-clause equivalent to one of the following:

const char* 
unsigned long long int 
long double 
char 
wchar_t 
char16_t 
char32_t 
const char*, std::size_t 
const wchar_t*, std::size_t 
const char16_t*, std::size_t 
const char32_t*, std::size_t 

、私は(doubleは、暗黙的になり、それが必要とされているかわかりませんあなたがタイプdoubleのリテラルを渡すことができるように)、long doubleに変換:

struct str {}; 

str operator"" _X(long double d) { 
    return str(); 
} 

int main() 
{ 
    str s = 4.0_X; 
} 
+3

[OK]を感謝を書くことができますので。しかし、なぜ ?つまり、二重にできないようにする文法には何かがあったのでしょうか? –

+5

@BérengerBerthoul: 'long double'の範囲と精度がそれ以上ある場合、なぜ' double'を使用しますか?おそらくスピードやメモリ使用の理由からでしょうか?コンパイル時に実行される操作のための考慮事項ではありません。倍精度の演算を実行する場合は、関数内で常にキャストを使用できます。 –

+0

@Ben Voigt [OK]をクリックします。私はちょうどそれがクルーギーの少しだと思うが、確かに大きな鉛はありません。ありがとう –

3

私はそれがあいまいな過負荷を防ぐためだと思います。あなたは以下のオーバーロードを定義することが許された場合、何があなたが上記のそれぞれにマップするソースコード内のユーザー定義リテラルの例を与えることができます

str operator"" _X(long double ld); 
str operator"" _X(double d); 
str operator"" _X(float f); 

を設定しますか?いいえ、リテラルを特定の浮動小数点データ型に制約する方法はありません。有用である可能性は何

がこのセットです:

str operator"" l_X(long double ld); 
str operator"" _X(long double d); 
str operator"" f_X(long double f); 

今あなたが

3.0_X // treated like a double 
3.0l_X // treated like a long double 
3.0f_X // treated like a float 
+0

可能ですが、そう思う。あなたが利益を得ることができるのであれば、足で自分を撃つことを可能にするために、C++の哲学に反するでしょう。そして確かにこれは利益をもたらすでしょう。例えば、私の実際のコードでは、構造体 "str"はテンプレートであり、特に "double"に対してインスタンス化されています。そして、そのために私は "長い倍の"トリックを使用することはできません(専門分野を除いて、しかし、これは本当にクラージーになります。部分的な特殊化は関数には許可されていません...) –

+1

@BérengerBerthoul:あなたの演算子は 'str 演算子"と書いても構いません。 "_X(long double ld){double d = ld;/* use d * /} ' –