我在x64 Linux上使用clang 9.0.1和gcc 9.2.1,都使用--std=c++17
(或--std=c++2a
)。
Gcc可以构建以下示例,而不会出现任何错误或警告,而clang ++在两行error: constexpr if condition is not a constant expression
上都报告if constexpr
。 (顺便说一句,在我的MacBook上,Apple clang-11.0.0也报告了相同的错误。)
MCVE:
#include <utility>
enum class TopicType {
MarketData = 'M',
Timer = 'T',
};
template<class Topic>
struct TopicBase {
constexpr static TopicType type() { return Topic::type; };
const Topic& topicImp;
explicit TopicBase(const Topic &t) : topicImp(t) {}
};
struct MarketDataTopic {
static constexpr TopicType type{TopicType::MarketData};
};
struct TimerTopic {
static constexpr TopicType type{TopicType::Timer};
};
template<class Topic>
int subscribe(TopicBase<Topic>&& topic) {
if constexpr (topic.type() == TopicType::MarketData) { // <-- clang++ reports error here
return 1;
}
if constexpr (topic.type() == TopicType::Timer) { // and error here
return 2;
}
return -1;
}
int main(int argc, const char **argv) {
MarketDataTopic m{};
TimerTopic t{};
TopicBase<MarketDataTopic> b1{m};
TopicBase<TimerTopic> b2{t};
subscribe(std::move(b1));
return 0;
}
在线编译器https://godbolt.org/z/rARi_N具有相同的结果。
那么哪个编译器是正确的?如果是错误,如何解决clang?
您可以执行此操作以使其适用于clang:
template<class Topic>
int subscribe(TopicBase<Topic>&& topic) {
using myType = TopicBase<Topic>;
if constexpr (myType::type() == TopicType::MarketData) { // <-- clang++ reports error here
return 1;
}
if constexpr (myType::type() == TopicType::Timer) { // and error here
return 2;
}
return -1;
}
最有可能是c的错误。更好地报告。