constとしてマークされたメンバー関数があり、メンバー変数のタイプを調べると、予期しない結果が得られます。
#include <iostream>
#include <string>
template<typename T>
struct type_printer;
class const_type_test {
public:
void test() const {
type_printer<decltype(value)> _;
}
int& test2() const {
return value;
}
void test3() const {
auto& x = value;
type_printer<decltype(x)> _;
}
void test4() const {
auto* x = &value;
type_printer<decltype(*x)> _;
}
private:
int value;
};
int main(int argc, char** argv)
{
const const_type_test x;
return 0;
}
私の理解では、constメソッドを使用している場合、メソッドは事実上名前がマングルされた名前であり、パラメーターの型はclassname const * constです。constメソッドのスコープでは、メンバー変数は事実上constである、つまり値はconstintになるといつも思っていました。ただし、コンパイラエラーを使用して型を推測すると、予期しない型が取得されます。
void const_type_test::test() const
:aggregateのエラー出力type_printer<int> _
は不完全な型であり、定義できません。type_printer<decltype(value)> _;
したがって、型がintとして推定されたことがわかります。値を変更できないので、constintになると思いました。decltypeを間違って使用していますか?または私は私の理解に穴があります。
私が尋ねる理由はtest2
、コンパイラーで文句を言うint&
からconst int
です。型の参照をバインドして修飾子を破棄します。それはまさに私が期待していることです。const参照をnonconst参照にバインドできます。
例3は、次のエラーを示しています。エラー:集計のtype_printer<const int&> _
型が不完全であり、定義できませんtype_printer<decltype(x)> _
。これは、const参照として推定されていると私が期待していることです。
例4:type_printer<const int&>
私がポインタだと思ったものも推測します。
私の知識の穴がどこにあるかを見つけるために、標準への参照を取得することに熱心です。また、使用時に奇妙なタイプの演繹ルールがあり、decltype
それが私をつまずかせているのではないかと思います。
decltype
クラスのメンバーには特別なルールがあります。メンバーの実際のタイプを返します。あなたがしたい場合decltype
(のconst関数内)コンテキストを考慮することが、あなたは括弧内の式をラップすることができます。
パランテシスなし:
void test() const {
type_printer<decltype(value)> _;
}
c.cpp:10:39: error: implicit instantiation of undefined template 'type_printer<int>'
type_printer<decltype(value)> _;
パランテシスあり:
void test() const {
type_printer<decltype((value))> _;
}
c.cpp:10:41: error: implicit instantiation of undefined template 'type_printer<const int &>'
type_printer<decltype((value))> _;
参照:
https://en.cppreference.com/w/cpp/language/decltype
引数が括弧で囲まれていないid式または括弧で囲まれていないクラスメンバーアクセス式である場合、decltypeはこの式で指定されたエンティティの型を生成します。そのようなエンティティがない場合、または引数がオーバーロードされた関数のセットを指定している場合、プログラムの形式は正しくありません。
https://docs.microsoft.com/en-us/cpp/cpp/decltype-cpp?view=vs-2019
式パラメーターが識別子またはクラスメンバーアクセスの場合、decltype(expression)は式で指定されたエンティティのタイプです。そのようなエンティティがない場合、または式パラメータがオーバーロードされた関数のセットを指定している場合、コンパイラはエラーメッセージを生成します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加