在今年的主题演讲中,Going Native C++的本质(转到40:30)Bjarne Stroustrup给出了以下代码示例:
template<typename C, typename V>
vector<Value_type<C>*> find_all(C& cont, V v)
{
vector<Value_type<C>*> res;
for (auto& x : cont)
if (x == v)
res.push_back(&x)
return res;
}
Run Code Online (Sandbox Code Playgroud)
此函数用于查找容器中所有值的值,并返回指向找到的元素的指针.视频中的示例:
string m{"Mary had a little lamb"};
for (const auto p: find_all(m,'a')) // p is a char*
if (*p != 'a')
cerr << "string bug!\n";
Run Code Online (Sandbox Code Playgroud)
我的问题是关于Value_Type<C>*.标准库中有这样的东西吗?我寻找它并没有找到它.如果它不在std中,怎么能实现呢?
我在标准中不知道这一点,但实施起来并不难:
template <class C>
struct value_type
{
typedef typename C::value_type type;
};
template <class T, int N>
struct value_type<T[N]>
{
typedef T type;
};
template <class T>
struct value_type<T*>
{
typedef T type;
};
Run Code Online (Sandbox Code Playgroud)
现在您可以typename value_type<C>::type用来访问容器包含的类型.如果您有自己想要使用的容器,但它没有value_typetypedef(无论出于何种原因您无法更改它),那么您也可以简单地为该容器专门化这个结构.
为了避免typename ...::type你可以这样做:
template <class C>
using Value_Type = typedef value_type<C>::type;
Run Code Online (Sandbox Code Playgroud)
现在你只是Value_Type<C>到处使用.
编辑
正如stefan在很快的回答中建议的那样,你可以更轻松地做到这一点std::begin,因为你使用/创建的任何容器都希望能够打电话std::begin和std::end无论如何:
template <class C>
using Value_Type = typename std::remove_reference<
decltype(*std::begin(std::declval<
typename std::add_lvalue_reference<C>::type>()))>::type;
Run Code Online (Sandbox Code Playgroud)
这更加简洁,虽然阅读时有点密集.它仍然比第一个选项更好,这将需要更少的自定义容器类型的样板代码.
| 归档时间: |
|
| 查看次数: |
3597 次 |
| 最近记录: |