Avr*_*dis 5 c++ templates decltype c++11
是否可以使用decltype来转换值?
例如,假设我们有以下模板:
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);*/
}
Run Code Online (Sandbox Code Playgroud)
它返回positionContainer中特定项的Item值.假设用户输入的位置大于容器的大小,在这种情况下我想返回一个铸造值,假设是一个铸造的零或其他东西.我不知道我的例子是否足够好,我的主要问题是:是否有可能使用一个值decltype,如果是,如何?
一般来说,你可以做到.例如:
int i = 0;
double d = 3.14;
i = static_cast<decltype(i)>(d);
Run Code Online (Sandbox Code Playgroud)
但是,请记住,您的函数返回一个引用(因为decltype(*(c.begin()))求值为引用类型):
std::vector<int> v;
static_assert(std::is_same<decltype(*v.begin()), int&>::value, "!"); // Won't fire
Run Code Online (Sandbox Code Playgroud)
在这种情况下,麻烦的是函数必须能够返回对类型对象的引用Container::value_type,但如果somevalue 具有不同的类型,则无法将引用返回给它Container::value_type&.
原因与您不允许执行以下操作的原因相同:
int i = 42;
float& f = static_cast<float&>(i);
Run Code Online (Sandbox Code Playgroud)
所以你需要问自己的第一件事是你的findInposition()函数是否应该真正返回对集合元素的引用(在这种情况下,你想要做什么是不可能的,就像上面的例子一样),或者更确切地说是按值返回该元素的副本.
如果是这种情况,并且您坚持使用decltype,则可以decltype通过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);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Run Code Online (Sandbox Code Playgroud)
但在我看来,以下内容更加清晰:
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);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Run Code Online (Sandbox Code Playgroud)