私はC++でCRTP(奇妙な再帰的テンプレートパターン)を学んでいます。CRTP(不思議な再帰的テンプレートパターン)が別のプライベートベースクラスの同じ名前の関数を選択しようとするのはなぜですか?
私はCRTPを学ぶために以下のコードを作った。
コードでは、基本クラスからCRTPの別の基本クラスを使用してイテレータを取得しようとしました。
gccコンパイラは、以下のtest_get_iterator_by_crtp()でGET_CONTAINRE_ITERATOR_CRTP :: begin()関数を選択できません。 GET_CONTAINRE_ITERATOR_CRTP <(int)> :: begin()の名前をbegin_another()に変更すると、gccがGET_CONTAINRE_ITERATOR_CRTP <(int)>およびContainerIterator <(int)>のbegin()を混乱させるようです。
私はci.template begin()を期待しました。以下はContainerIterator :: begin()にできません。これはプライベートベースクラスとして実装されており、直接アクセスできないためです。
begin()があいまいである理由を教えてください。 私が簡単な間違いや誤解をした場合、私を許してください。どうもありがとうございました。
template <typename T>
class ContainerIterator : public std::vector<T> {
public:
auto begin(void) {
return std::vector<T>::begin();
}
};
template <typename Derived>
class GET_CONTAINRE_ITERATOR_CRTP {
public:
template <typename T>
auto begin(void) {
Derived* host = static_cast<Derived*>(this);
// The following line makes a compile error of ambiguous name, begin().
return host->template ContainerIterator<T>::begin();
}
};
// CI = Container Iterator
class CI : private ContainerIterator<int>, public GET_CONTAINRE_ITERATOR_CRTP<CI> {
public:
friend class GET_CONTAINRE_ITERATOR_CRTP<CI>;
};
void test_get_iterator_by_crtp(void) {
CI ci{};
auto it = ci.template begin<int>();
}
エラーメッセージ:
error: request for member ‘begin’ is ambiguous
私のためにコンパイルします。 Apple clang 8.0.0(clang-800.0.42.1) –
@Richard Hodges:報告していただきありがとうございます。私のコンパイラはgcc(Ubuntu 5.4.0-6ubuntu1〜16.04.4)5.4.0 20160609. – mora