如果成员存在,则为C ++设置值

时间:2017-08-31 06:25:11

标签: c++

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

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

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

2 个答案:

答案 0 :(得分: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);
    // ...
}

答案 1 :(得分:0)

使用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);
}