特定のオブジェクトの範囲コンストラクタを実装したいが、2つの入力イテレータのみを受け入れるように制限したい。typeidを使って入力イテレータしか受け付けないようにコンストラクタを実装する方法は?
私はこのコードをgcc 7.1.0でコンパイルしようとしました。
ファイルtest.cpp
#include <vector>
#include <type_traits>
#include <typeinfo>
template <typename Iterator>
using traits = typename std::iterator_traits<Iterator>::iterator_category;
template <typename T>
class A{
private:
std::vector<T> v;
public:
template <typename InputIterator,
typename = std::enable_if_t<
typeid(traits<InputIterator>) ==
typeid(std::input_iterator_tag)>
>
A(InputIterator first, InputIterator last) : v(first, last) {}
};
int main(){
std::vector<double> v = {1, 2, 3, 4, 5};
A<double> a(v.begin(), v.end());
}
私はg++ test.cpp -o test
と、このコンパイルエラーを取得:
test.cpp: In function ‘int main()’:
test.cpp:27:34: error: no matching function for call to ‘A<double>::A(std::vector<double>::iterator, std::vector<double>::iterator)’
A<double> a(v.begin(), v.end());
^
test.cpp:22:7: note: candidate: template<class InputIterator, class> A<T>::A(InputIterator, InputIterator)
A(InputIterator first, InputIterator last) : v(first, last) {}
^
test.cpp:22:7: note: template argument deduction/substitution failed:
test.cpp: In substitution of ‘template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type [with bool _Cond = ((const std::type_info*)(& _ZTISt26random_access_iterator_tag))->std::type_info::operator==(_ZTISt18input_iterator_tag); _Tp = void]’:
test.cpp:18:16: required from here
test.cpp:19:49: error: call to non-constexpr function ‘bool std::type_info::operator==(const std::type_info&) const’
typeid(traits<InputIterator>) ==
test.cpp:18:16: note: in template argument for type ‘bool’
typename = std::enable_if_t<
^~~~~~~~
test.cpp:10:7: note: candidate: A<double>::A(const A<double>&)
class A{
^
test.cpp:10:7: note: candidate expects 1 argument, 2 provided
test.cpp:10:7: note: candidate: A<double>::A(A<double>&&)
test.cpp:10:7: note: candidate expects 1 argument, 2 provided
コンストラクタのために、より適しているので、私は、デフォルトのテンプレートパラメータを使用することにしました。オペレータtypeid()
を使用するのは、コードを修正するときに読むのが本当に簡単だからですが、どのような方法でも動作させることはできません。
他の解決策は非常に奇妙で、実際にはわかりにくいです(InputIteratorパラメータに* itや++などの特定のメソッドを持たせるなど)。私がこれを行う方法がない場合は、多かれ少なかれ、読みやすいソリューションに感謝します。
私はこのアイデアを考えたことがありません。理解して実装するのは簡単です。どうもありがとうございました! –