gpt4 book ai didi

c++ - 使用无效方法实例化类模板

转载 作者:行者123 更新时间:2023-11-30 01:17:02 26 4
gpt4 key购买 nike

我正在写一个类 IteratorIterable它包装了一个容器类(一个带有 begin()end() 方法并返回一些迭代器的类),以便可以迭代包装类的迭代器。这个想法是基于this post .我的代码如下所示(为简洁起见省略了一些方法):

template <class T>
class IteratorIterable
{
private:
T& container;

public:
typedef decltype(container.begin()) BackendIterator;

public:
class IteratorIterator
{
public:
IteratorIterator() : it() {}
IteratorIterator(BackendIterator it) : it(it) {}
IteratorIterator(const IteratorIterator& other) : it(other.it) {}

IteratorIterator& operator=(const IteratorIterator& other) { if (&other == this) return *this; it = other.it; return *this; }

BackendIterator operator*() const { return it; }
const BackendIterator* operator->() const { return &it; }

bool operator==(const IteratorIterator& other) { return it == other.it; }
bool operator !=(const IteratorIterator& other) { return it != other.it; }

IteratorIterator operator+(size_t n) { return IteratorIterator(it + n); }

IteratorIterator& operator++() { ++it; return *this; }
IteratorIterator operator++(int) { IteratorIterator cpy(*this); ++(*this); return cpy; }

private:
BackendIterator it;
};

public:
IteratorIterable(T& container) : container(container) {}

IteratorIterator begin() const { return IteratorIterator(container.begin()); }
IteratorIterator end() const { return IteratorIterator(container.end()); }
};


template <class T>
IteratorIterable<T> ItIt(T& container)
{
return IteratorIterable<T>(container);
}

这里的问题是,operator+() IteratorIterator 中的方法仅对随机访问有效 BackendIterator ,因为否则加法运算符没有在后端定义。我希望我的 IteratorIterator 仅在后端支持时才提供此方法。

考虑这个示例代码:

typedef list<int> Cont;

Cont vec = {1, 2, 3, 4, 5, 6, 7, 8, 9};

IteratorIterable<Cont> itb(vec);

IteratorIterable<Cont>::IteratorIterator beg = itb.begin();
IteratorIterable<Cont>::IteratorIterator it = beg;

it++;
//it = beg+1;

printf("%d\n", **it);

这在使用 it++ 时编译得很好行,但是 - 正如预期的那样 - 因 it = beg+1 而失败行,因为 list<int>::iterator不是随机访问。我想这是因为如果我实际上不实例化 IteratorIterator::operator+() ,编译器不关心。

我知道模板只允许对某些模板参数有效,但这里是模板化的,而不是方法。当某个方法从未用于此特定实例化时实例化一个方法无效的类模板是否正确? GCC 和 Clang 没有提示,但它是否符合 C++ 标准?

最佳答案

是的,标准保证类模板的隐式实例化只会导致声明的隐式实例化,而不是成员函数的定义。

§14.7.1 [temp.inst]

1   ... The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions, default arguments, or exception-specifications of the class member functions, member classes, scoped member enumerations, static data members and member templates; and it causes the implicit instantiation of the definitions of unscoped member enumerations and member anonymous unions.

11   An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instantiation....

请注意,如果您显式实例化类,无论您是否使用operator+,您的代码都将无法编译

template class IteratorIterable<std::list<int>>;

除非 BackendIterator 是随机访问迭代器,否则您可以通过对 SFINAE 重载集的成员函数使用 enable_if 来防止这种情况。

template<typename Iter = BackendIterator>
typename std::enable_if<
std::is_same<typename std::iterator_traits<Iter>::iterator_category,
std::random_access_iterator_tag>::value,
IteratorIterator>::type
operator+(size_t n)
{
return IteratorIterator(it + n);
}

Live demo

关于c++ - 使用无效方法实例化类模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25397011/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com