问题描述
是否可以使用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转换值,可以吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!