1. ホーム
  2. c++

c++のコンストラクタが非クラス型であるオッドボール問題

2022-02-14 22:31:04
<パス

奇妙な問題で、明らかに本のコードを真似て小さな試みをした結果

error: request for member 'push' in 's', which is of non-class type 'T_stack
()'
|codes


ここで、テンプレートクラスを試してみたいと思います。すると、何かが間違っていた。

template <typename T> class T_stack{
public:
    typedef typename std::vector<T>::size_type size_type;

    T_stack<T>():data(std::make_shared<std::vector<T>>()){}
    //T_stack
(std::initializer_list
);

    bool empty(){return data->empty();}
    void push( T &t){data->push_back(t);}
    void push(const T &&t){data->push_back(t);}
    //void pop();
    T &top();
private:
    std::shared_ptr<std::vector<T>> data;
};
template <typename T>
void T_stack<T>::pop(){
    data-> pop_back();
}
template <typename T>
T &T_stack<T>::top(){
    return data->back();
}
/*template 

T_stack::T_stack
(std::initializer_list
 il){

}*/

int main()
{
    T_stack<int> s();
    s.push(5);
    std::cout << s.top();
}


コンパイラはエラーを報告し、エラーコードはちょうど問題があるのはpush関数であると仮定してpush関数で報告されます。実際には、コンストラクタで発生しています。むしろ不思議です。
を使ったからなんです。 T_stack<int> s() というのがあり、それが原因でした。

のような引数のないコンストラクタは T_stack<T>() は、オブジェクト宣言でも関数宣言でもかまいません。しかし、c++コンパイラは、常にオブジェクトよりも関数宣言を優先します。

この曖昧さを回避する方法をいくつか調べてみました。

1. オブジェクトを()で初期化しない。

T_stack<int> s



2. 大括弧 {} を使って、オブジェクトを初期化します。
T_stack<int> s{};



3. 代入演算子と匿名のデフォルトを使用して構築されたオブジェクト。 T_stack<int> s = T_stack<int> {} .