[英]How do I static_assert the type that an iterator dereferences to?
template <typename InputIterator>
MyFun(const InputIterator begin, const InputIterator end)
{
// I want to static_assert that decltype(*begin) == SomeType
}
我怎樣才能做到這一點? 我在想static_assert(std::is_same<*InputIterator,SomeType>)
但這當然不起作用......
static_assert(is_same<typename std::iterator_traits<InputIterator>::value_type,
SomeType>::value, "");
另一種使用decltype
的替代方法,並附帶一個注釋,該注釋通常會產生引用(但可能不會!)。
// If you want to assert that the dereferenced item is indeed a reference
static_assert(std::is_same<decltype(*begin), SomeType&>::value, "");
// If you are only interested in the "bare" type
// (equivalent to Jesse's providing iterator_traits was properly specialized)
static_assert(std::is_same<
typename std::remove_reference<decltype(*begin)>::type,
SomeType
>::value, "");
我寧願使用std::is_convertible
而不是std::is_same
和const SomeType&
而不是SomeType
因為通常,我們需要從迭代器中轉換為const SomeType&
。
static_assert(
std::is_convertible<decltype(*begin), const SomeType&>::value,
"Input parameters must be iterators over objects convertible to 'SomeType'."
);
此外,如果要通過迭代器修改數據,則const SomeType&
應更改為SomeType&
。 這在繼承的情況下非常有用,在這種情況下,子對象上的迭代器被傳遞給接收父類迭代器的函數。
下面是一個具體的例子:
#include <type_traits>
#include <vector>
#include <iostream>
struct Animal {
int x;
inline void print() const {
std::cout << "x = " << x << std::endl;
}
inline int modify() {
return ++x;
}
virtual ~Animal() = default;
};
struct Cat: public Animal {
};
struct Dog: public Animal {
};
template<typename I>
inline void printAnimals(I begin, I end) {
static_assert(
std::is_convertible<decltype(*begin), const Animal&>::value,
"Input parameters must be iterators over objects of type 'Animal'."
);
for (I it = begin; it != end; ++it) {
const Animal& a = *it;
a.print();
}
std::cout << "---------" << std::endl;
}
template<typename I>
inline void modifyAnimals(I begin, I end) {
static_assert(
std::is_convertible<decltype(*begin), Animal&>::value,
"Input parameters must be iterators over objects of type 'Animal'."
);
for (I it = begin; it != end; ++it) {
Animal& a = *it;
a.modify();
}
}
int main() {
std::vector<Dog> dogs(2);
dogs[0].x = 10;
dogs[1].x = 20;
printAnimals(dogs.begin(), dogs.end());
modifyAnimals(dogs.begin(), dogs.end());
printAnimals(dogs.begin(), dogs.end());
std::vector<Cat> cats(3);
cats[0].x = 100;
cats[1].x = 110;
cats[2].x = 120;
printAnimals(cats.begin(), cats.end());
modifyAnimals(cats.begin(), cats.end());
printAnimals(cats.begin(), cats.end());
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.