使用decltype转换值

使用decltype转换值

本文介绍了使用decltype转换值,可以吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用decltype强制转换值?

Is it possible to use decltype to cast a value?

例如,假设我们具有以下模板:

For example let's say that we have the following template:

template<typename Container>
auto findInposition(Container& c,int position)->decltype(*(c.begin()))
{
  if(std::distance(c.begin(),c.begin()+position)<c.size())
  return c.at(p);
  /*else
    return decltype(*(c.begin())(somevalue);*/
}

会返回容器中特定位置处某个项目的值,假设用户输入的位置大于容器的大小,在这种情况下,我想返回一个强制转换的值,比如强制转换为零或其他内容,我不知道我的示例是否足够好,我的主要问题是:是否可以强制转换使用 decltype 的值,如果是的话,怎么做?

which returns the value of an Item at a specific position in a Container. Let's say that the user enters a position greater than the size of the container, in this situation I want to return a casted value, let's say a casted zero or something. I don't know if my example is good enough, my main question is: Is it possible to cast a value using decltype and if yes how?

推荐答案

int i = 0;
double d = 3.14;
i = static_cast<decltype(i)>(d);

请注意,您的函数会返回 reference (因为 decltype(*(c.begin()))会得出引用类型):

However, keep in mind your function returns a reference (because decltype(*(c.begin())) evaluates to a reference type):

std::vector<int> v;
static_assert(std::is_same<decltype(*v.begin()), int&>::value, "!"); // Won't fire

在这种情况下,麻烦的是该函数必须能够返回a引用类型为 Container :: value_type 的对象,但是如果 somevalue 具有不同的类型,则不会能够以 Container :: value_type& 的形式返回对其的引用。

What's troublesome in this situation is that the function must be able to return a reference to an object of type Container::value_type, but if somevalue has a different type, you won't be able to return a reference to it as a Container::value_type&.

原因与您相同不允许执行以下操作:

The reason is the same why you are not allowed to do the following:

int i = 42;
float& f = static_cast<float&>(i);

所以您首先要问自己的是您的 findInposition() 函数实际上应该返回对集合元素的引用(在这种情况下,就像上面的示例一样,您无法执行的操作),或者更确切地说,是按值返回 该元素的副本。

So the first thing you need to ask yourself is whether your findInposition() function should really return a reference to the element of the collection (in which case, what you want to do is not possible, just like the example above), or rather return by value a copy of that element.

如果是这种情况,并且您坚持使用 decltype ,可以通过:

If that is the case, and you insist on using decltype, you may transform the output of decltype through std::decay:

#include <type_traits>

template<typename Container>
auto findInposition(Container& c,int position) ->
    typename std::decay<decltype(*c.begin())>::type
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
  if(std::distance(c.begin(),c.begin()+position)<c.size())
    return c.at(position);
  else
    return static_cast<
        typename std::decay<decltype(*c.begin())>::type>(somevalue);
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

但是在我看来,以下内容更加清晰:

But in my opinion the following is much clearer:

template<typename Container>
auto findInposition(Container& c,int position) ->
    typename Container::value_type
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
  if(std::distance(c.begin(),c.begin()+position)<c.size())
    return c.at(position);
  else
    return static_cast<typename Container::value_type>(somevalue);
//                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

这篇关于使用decltype转换值,可以吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 00:16