编译时检测T是否是引用成员

问题描述 投票:0回答:1

我试图在编译时检测参数是否是引用成员。它没有抓住它,我不明白为什么。

#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
}

我做错了什么?

c++ constexpr compile-time-type-checking
1个回答
1
投票

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)
    • 这可能通过扩展为
      Field<decltype(a_.i2)>(a_.i2)
    • 的宏来实现
© www.soinside.com 2019 - 2024. All rights reserved.