2017-01-21 9 views
4

私はcppreference page for user definedリテラルを見て取っていた定義、と私はいくつかの例 ユーザー定義リテラルは

template <char...> double operator "" _π(); // OK 

以外のすべてを理解すると思いますどのようにこの演算子の動作しますか?どのようにそれを呼び出すことができますか?

double operator"" _Z(long double); // error: all names that begin with underscore 
            // followed by uppercase letter are reserved 
double operator""_Z(long double); // OK: even though _Z is reserved ""_Z is allowed 

上記2つの機能の違いは何ですか?最初の関数がエラーでなかった場合、2番目の関数とは違って最初の関数を呼び出す際の違いは何ですか?

ありがとうございます!

答えて

6
このオペレータの作業を行いどのよう
template <char...> double operator "" _π(); // OK 

を見てみると

long double d = 45_deg; 

?どのようにそれを呼び出すことができますか?

1.234_πoperator "" _π<'1', '.', '2', '3', '4'>()となります。この形式では、通常は検出されないスペルの違いを検出できます(1.21.20など)。long doubleでも正確に表現できないため、丸めの問題を避けることができます。1.2

double operator"" _Z(long double); // error: all names that begin with underscore 
            // followed by uppercase letter are reserved 
double operator""_Z(long double); // OK: even though _Z is reserved ""_Z is allowed 

上記の二つの機能の違いは何ですか?

は、C++標準では、一種の言葉として解釈できるトークン、という点で文法を定義します。"" _Zは、2つのトークン、""および_Zです。 ""_Zは単一のトークンです。

この区別は重要:#define S " world!"与えられ、その後、"Hello" S、空白は、ユーザー定義リテラルの接尾辞として見られることからそれを防止すること、Sスタンドアロンのトークンを作るものです。

は容易符号化のため、これらの機能を定義する場合の両方"" _Z""_Z構文は、一般的に許容されるが、"" _Z構文は識別子として見られるように_Zを必要とします。これは、実装がマクロとして_Zをあらかじめ定義している場合、またはカスタムキーワードとして宣言した場合に問題を引き起こす可能性があります。

+0

なぜ '_π'リテラルで何か"_π'が '演算子"を呼び出さない理由を知っていますか? "_π"、 "o"、 "m"、 "e"、 "t" 'h'、 'i'、 'n'、 'g'>() '?どのようにそれらの文字をテンプレート引数として渡すように、そのユーザー定義リテラルの宣言を変更することができますか? – Curious

+0

@Curious個々の文字をテンプレート引数として渡すことは、数値リテラルでのみ可能です。 – hvd

+0

それはなぜそう思う?私はなぜ文字がサポートされないのか理解できません。 – Curious

1

私が理解する限り、2つの兆候の間に違いはありません。

識別子_Zは、標準で技術的に予約されているという問題があります。主な違いは、スペースがあることである:スペースを削除

double operator""/*space*/_Z(long double); 

double operator""_Z(long double); 

は、基本的には、理論的には、エラー(または可能性が高い警告を)抑えるだろう回避策です。

あなたがそれらをどのように使用するかについては、あなたがリストしたリンクの例を見ましたか?

#include <iostream> 

// used as conversion 
constexpr long double operator"" _deg (long double deg) 
{ 
    return deg*3.141592/180; 
} 

// used with custom type 
struct mytype 
{ 
    mytype (unsigned long long m):m(m){} 
    unsigned long long m; 
}; 
mytype operator"" _mytype (unsigned long long n) 
{ 
    return mytype(n); 
} 

// used for side-effects 
void operator"" _print (const char* str) 
{ 
    std::cout << str; 
} 

int main(){ 
    double x = 90.0_deg; 
    std::cout << std::fixed << x << '\n'; 
    mytype y = 123_mytype; 
    std::cout << y.m << '\n'; 
    0x123ABC_print; 
} 

ユーザ定義リテラルの背後にある考え方は、別の型にリテラルに内蔵された変換することができるタイプに内蔵されたにも適用することができるオペレータの作成を可能にすることです。

EDIT:

あなただけのリテラル値の末尾にオペレータを追加する必要があり、これらの演算子のいずれかを呼び出します。だから、与えられた:

// used as conversion 
constexpr long double operator"" _deg (long double deg) 
{ 
    return deg*3.141592/180; 
} 

呼び出し元のコードは、例えば次のようになります。限りtemplate <char...> double operator "" _π();を使用すると、たぶんthis.

+0

リンクの例を見ましたが、2つの '_Z'演算子の違いを理解していませんでした。' _Z'が予約されていない場合はどうしたらいいですか?それはまた、ユーザー定義のリテラルですか?余分なスペースはどういう意味ですか?また、 '_π'部分は未回答のままでした。 – Curious

+0

申し訳ありませんが、私は私の質問ではっきりしているとは思わない。私が2つの '_Z 'の違いについて聞いてみたのは、スペースが意味するところはなんですか?私は通常の場合にオペレータに電話する方法を知っていますが、スペースはどういう意味ですか?それはいつもエラーですか? – Curious

+0

@Curious - あなたが[cppreference](http://en.cppreference.com/w/cpp/language/user_literal)を十分に読んだら、 '' "_Z'(スペースなし)はOKですが、 '_Z'は予約されています。また、 'if'がキーワードであるにもかかわらず、もっと複雑な' complex 'リテラル' '' if'(再びスペースなし)が動作しなければならないことも示しています。 –

関連する問題