我正在尝试根据是否将 l 或 r 值传递给函数来存储引用成员变量或移动构造值成员变量。这是我试过的。是否有关于如何获得我想要的功能的指导?
尝试 1
template <class T>
struct ARR
{
ARR(T o) : obj(std::forward(o)) {}
typename std::conditional<std::is_lvalue_reference<T>::value, std::decay<T>::type &, std::decay<T>::type>::type obj;
};
template <class T>
void make_ARR(T && o)
{
ARR<decltype(o)> t(std::forward(o));
}
尝试 2
template <class T>
struct ARR
{
};
template <class T>
struct ARR <T &&>
{
ARR(T o) : obj(std::move(o)) {}
typename std::decay<T>::type obj;
};
template <class T>
struct ARR <T &>
{
ARR(T o) : obj(o) {}
typename std::decay<T>::type & obj;
};
template <class T>
void make_ARR(T && o)
{
ARR<decltype(o)> t(std::forward(o));
}
最佳答案
在调试器中检查以下内容的最终结果似乎表明这就是您要查找的内容,即使该类的语义可能不是您所追求的。
template<bool> class val_or_ref;
template<>
class val_or_ref<false> {
public:
template<typename T>
struct ARR {
public:
T obj;
ARR(T &&value) : obj(std::move(value)) {}
};
template<typename T>
static ARR<T> make(T &&t)
{
return ARR<T>(std::forward<T>(t));
}
};
template<>
class val_or_ref<true> {
public:
template<typename T>
struct ARR {
public:
T &obj;
ARR(T &value) : obj(value) {}
};
template<typename T>
static ARR<T> make(T &t)
{
return ARR<T>(t);
}
};
template<typename T>
auto make_ARR(T &&t)
-> decltype(val_or_ref<std::is_lvalue_reference<T>::value>
::make(std::forward<T>(t)))
{
return val_or_ref<std::is_lvalue_reference<T>::value>
::make(std::forward<T>(t));
}
综合以上,得到以下结果:
int n=4;
auto a=make_ARR(7);
auto b=make_ARR(n);
gdb
告诉我:
(gdb) p a
$1 = {obj = 7}
(gdb) p b
$2 = {obj = @0x7fffffffe384}
(gdb) p &a
$3 = (val_or_ref<false>::ARR<int> *) 0x7fffffffe380
(gdb) p &b
$4 = (val_or_ref<true>::ARR<int> *) 0x7fffffffe370
(gdb) p b.obj
$5 = (int &) @0x7fffffffe384: 4
可能还有其他更紧凑的方式来做到这一点,但这似乎是不言自明的。
关于c++ - 基于 L 或 R 值模板的成员变量类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26290539/