【问题标题】:C++ set value if member exists如果成员存在,则 C++ 设置值
【发布时间】:2017-08-31 06:25:10
【问题描述】:
template<typename T>
if (std::is_same<T, FrontCameraSegment>::value) {
    height = segment.height;
}

我有一个模板来处理多个传感器。一个给我一个高度属性,其他的没有。我的代码中需要该值一次,Visualize() 函数的其余部分对于每个传感器都是相同的。 所以我想检查 T is_same 是否与 FrontCameraSegment 一起,然后我想使用 segment.height 属性一次。 但是,编译器说"height" 不是传递给T 的所有元素的成员,这是逻辑。 由于同样的原因,演员表不起作用。 使用继承重构传感器是不可能的(我不能做那部分)。

所以我的问题是:我如何告诉编译器我检查了height 是一个成员?

【问题讨论】:

  • 您需要根据std::is_same&lt;T, FrontCameraSegment&gt;::value的结果为您的模板提供专业化
  • @LogicStuff 感谢您指出正确的答案。但我不同意这是重复的。重复意味着重复的问题,在这种情况下,它只是对两个不同问题的相同答案。另请参阅 meta.stackoverflow.com/a/266246/1023911meta.stackoverflow.com/q/292329/1023911
  • @WernerHenze - 不,重复意味着相同的答案。这就是为什么在关闭时,关闭布局的标题为“This question has a answer here:”。当然,答案也必须易于应用。
  • @StoryTeller 但是您链接的问题和答案仅适用于支持 C++17 的编译器,因此受限于旧标准的人不会搜索 constexpr if,但更有可能搜索更通用的像OP一样回答(例如SFINAE)。所以问题比 C++17 更普遍

标签: c++


【解决方案1】:

在 C++17 中,您可以在以下情况下使用 constexpr:

template<typename T>
void foo(T& segment)
{
    if constexpr (std::is_same<T, FrontCameraSegment>::value) {
       height = segment.height;
    }
    // ...
}

在此之前,您必须使用一些专业化/调度:

// fallback
template<typename T>
void setHeightIfPossible(float& height, const T& segment) { /* Empty */ }

void setHeightIfPossible(float& height, const FrontCameraSegment& segment) {
    height = segment.height;
}

template<typename T>
void foo(T& segment)
{
    // ...
    setHeightIfPossible(height, segment);
    // ...
}

【讨论】:

    【解决方案2】:

    使用 enable-if-style 仿函数来选择性地应用高度,例如:

    #include <utility>
    #include <iostream>
    
    namespace notstd {
        template<typename... Ts> struct make_void { typedef void type;};
        template<typename... Ts> using void_t = typename make_void<Ts...>::type;
    }
    struct Sensor1
    {
        int width;
    };
    
    struct Sensor2
    {
        int width;
        int height;
    };
    
    template<class Sensor, typename = void>
    struct height_reader
    {
        template<class SensorArg>
        void operator()(SensorArg&& source, int& target) const
        {
            // no-op
        }
    };
    
    template<class Sensor>
    struct height_reader<Sensor, 
        notstd::void_t<decltype(std::declval<Sensor>().height)>> 
    {
        template<class SensorArg>
        void operator()(SensorArg&& source, int& target) const
        {
            target = source.height;
        }
    };
    
    
    struct Readings
    {
        int width = 0, height = 0;
        template<class Sensor> void apply_sensor(Sensor&& sensor)
        {  
            width = sensor.width;
            height_reader<Sensor> hr;
            hr(sensor, height);
        }
    
    };
    
    void emit(int i)
    {
        std::cout << i << std::endl;
    }
    
    int main()
    {
        Sensor1 s1 { 1 };
        Sensor2 s2 { 2, 3 };
    
        Readings r;
        r.apply_sensor(s1);
        r.apply_sensor(s2);
        emit(r.height);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-10
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 2023-03-03
      • 2011-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多