我正在尝试将C ++ 03中的SFINAE应用于std::vector
克隆(用于教育目的),以限制传递给构造函数的迭代器类型:
struct input_iterator_tag {};
struct output_iterator_tag {};
struct InputIter {
typedef input_iterator_tag iterator_category;
};
struct OutputIter {
typedef output_iterator_tag iterator_category;
};
template<class T>
class Vector {
public:
explicit Vector(size_t, T=T());
template <class InputIt>
Vector(InputIt, InputIt, input_iterator_tag = typename InputIt::iterator_category());
};
template<class T>
Vector<T>::Vector(size_t, T)
{
std::cout << "size_t overload called" << std::endl;
}
template<class T>
template <class InputIt>
Vector<T>::Vector(InputIt, InputIt, input_iterator_tag)
{
std::cout << "input iterator overload called" << std::endl;
}
int main(int argc, char* argv[])
{
InputIter input;
OutputIter output;
Vector<int> a(0, 0);
Vector<int> b(input, input);
// Should fail to compile:
Vector<int> c(output, output);
}
编译器(g ++ - 4.9)正确拒绝向量c
的定义(传递了错误的迭代器类型),但也拒绝了向量a
的定义,但失败了:
sfinae.cpp: In constructor 'Vector<T>::Vector(InputIt, InputIt, input_iterator_tag) [with InputIt = int; T = int]':
sfinae.cpp:42:23: error: 'int' is not a class, struct, or union type
Vector<int> a(0, 0);
^
sfinae.cpp:42:23: note: when instantiating default argument for call to Vector<T>::Vector(InputIt, InputIt, input_iterator_tag) [with InputIt = int; T = int]
为什么替换失败归类为错误?