如何从通过概念传递的参数中获取类型别名?
How to get typename aliases from an argument passed via concept?
我们来看看下面的代码:
#include <iostream>
#include <vector>
#include <iterator>
template<typename T>
concept Iterable = std::is_same_v<decltype(begin(std::declval<T>())), decltype(end(std::declval<T>()))>;
void print(const Iterable auto& c) {
std::copy(begin(c), end(c), std::ostream_iterator<???::value_type>(std::cout, ", "));
}
int main () {
std::vector v{{10,20,30,40,50}};
print(v);
return 0;
}
我想知道应该写什么来代替 ???::value_type
,因为在变量的定义中没有适当的类型限定。
假设你的意思是获取类型的嵌套 typedef,只是不要使用缩写函数模板语法:
template <Iterable C>
void print(C const& c) {
std::copy(begin(c), end(c),
std::ostream_iterator<typename C::value_type>(std::cout, ", "));
}
这使您有机会以 C
甚至不是引用类型的方式命名类型。
如果你真的想坚持使用缩写函数模板语法,你必须这样做:
void print(const Iterable auto& c) {
using C = std::remove_reference_t<decltype(c)>;
std::copy(begin(c), end(c),
std::ostream_iterator<typename C::value_type>(std::cout, ", "));
}
请注意,您不需要对概念使用 decvlal
,您可以使用 requires-expression:
template<typename T>
concept Iterable = requires (T t) {
requires std::is_same_v<decltype(begin(t)), decltype(end(t))>;
};
稍微好一点。
我们来看看下面的代码:
#include <iostream>
#include <vector>
#include <iterator>
template<typename T>
concept Iterable = std::is_same_v<decltype(begin(std::declval<T>())), decltype(end(std::declval<T>()))>;
void print(const Iterable auto& c) {
std::copy(begin(c), end(c), std::ostream_iterator<???::value_type>(std::cout, ", "));
}
int main () {
std::vector v{{10,20,30,40,50}};
print(v);
return 0;
}
我想知道应该写什么来代替 ???::value_type
,因为在变量的定义中没有适当的类型限定。
假设你的意思是获取类型的嵌套 typedef,只是不要使用缩写函数模板语法:
template <Iterable C>
void print(C const& c) {
std::copy(begin(c), end(c),
std::ostream_iterator<typename C::value_type>(std::cout, ", "));
}
这使您有机会以 C
甚至不是引用类型的方式命名类型。
如果你真的想坚持使用缩写函数模板语法,你必须这样做:
void print(const Iterable auto& c) {
using C = std::remove_reference_t<decltype(c)>;
std::copy(begin(c), end(c),
std::ostream_iterator<typename C::value_type>(std::cout, ", "));
}
请注意,您不需要对概念使用 decvlal
,您可以使用 requires-expression:
template<typename T>
concept Iterable = requires (T t) {
requires std::is_same_v<decltype(begin(t)), decltype(end(t))>;
};
稍微好一点。