web-dev-qa-db-ja.com

ユーザー定義の文字列リテラルと整数リテラルの動作が異なるのはなぜですか?

私はユーザー定義のリテラルについて学んでいて、次のテストコードと混同しています。

std::chrono::seconds operator"" _s(unsigned long long s) {
    return std::chrono::seconds(s);
}

std::string operator"" _str(const char *s, std::size_t len) {
    return std::string(s, len);
}

int main() {
    auto str = "xxxxx"_str;
    std::cout << str.size() << std::endl;    // works

    auto sec = 4_s;
    std::cout << sec.count() << std::endl;   // works

    std::cout << "xxxxx"_str.size() << std::endl;   // works

    std::cout << 4_s.count() << std::endl;   // does **NOT** work!

    return 0;
}

コンパイラは次のエラーメッセージを表示します。

エラー:タイプ 'unsigned longlong'または 'const char *'の引数を持つ 'operator "" _ s.count'の呼び出しに一致するリテラル演算子がなく、一致するリテラル演算子テンプレートがありません
cout << 4_s.count()<< endl;

ユーザー定義のリテラルとして_ s.countが必要なようです。また、浮動小数点リテラルは整数リテラルのように動作します。

ユーザー定義の整数リテラルと文字列リテラルの動作が異なるのはなぜですか?

21
for_stack

このように浮動小数点リテラルが機能します!!

括弧のペアを追加すると、機能するはずです。

_std::cout << (4_s).count();
_

または、それらを分離します(コンパイラーがそれを不正な形式の分数定数浮動小数点リテラルとして解釈しないようにするため)。

_std::cout << 4_s .count();
//              ^ Space here!
_

参照: CppReference.com

上記のリファレンスのNotesセクションでは、

最大のムンクのため、[pP、(C++ 17以降)] eおよびEで終わるユーザー定義の整数および浮動小数点リテラル。その後に演算子_+_または_-_、- ソース内の演算子から空白で区切る必要があります

_long double operator""_E(long double);
long double operator""_a(long double);
int operator""_p(unsigned long long);

auto x = 1.0_E+2.0;  // error
auto y = 1.0_a+2.0;  // OK
auto z = 1.0_E +2.0; // OK
auto w = 1_p+2;      // error
auto u = 1_p +2;     // OK
_

したがって、小数点として使用されるドットに関しては、背後にあるものから分離する必要があります。そうしないと、浮動小数点数の一部として扱われます。

上記の例をCppReferenceからテストしたところ、verysilimarエラーメッセージが表示されました。

_test.cpp:19:10: error: unable to find numeric literal
operator 'operator""_E+2.0'
                    ^^^^^^
 auto x = 1.0_E+2.0;  // error
_

__E+2.0_が全体としてどのように見なされるかud-suffixがわかりましたか?


私の最初の説明の試みは、この投稿の 改訂履歴 にあります。

18
iBug