我试图在编译时检测引用。它没有抓住它,我不明白为什么。
#include <type_traits>
struct a {
a(): i1(42), i2(i1){}
int i1;
int& i2;
};
template <typename T>
void Field(T &field) {
if constexpr (std::is_pointer_v<T>) {
//handle pointer
} else if constexpr (std::is_reference_v<T>) {
static_assert(!std::is_reference_v<T>, "Reference not supported");
} else {
//handle value
}
}
int main()
{
a a_;
Field(a_.i2); // I want this to fail at compile time, but it's not
}
我做错了什么?
std::is_reference_v
原则上可以工作,但与您使用它的方式不同。您有一个函数模板 Field(T &field)
,其中模板类型参数 T
不会被推导为引用。
a a_;
Field(a_.i2); // calls Field<T>(T&) with [T = int]
// std::is_reference_v<int> is false
无论您想在这里做什么,您都可以:
std::reference_wrapper
并始终接受值参数 T field
std::type_identity_t<T> field
参数来禁用扣除,这会强制用户手动调用 Field<int&>(a_.i2)