【问题标题】:clang and gcc disagree when calling static constexpr member function on a type deduced from an l-value reference type在从左值引用类型推导出的类型上调用静态 constexpr 成员函数时,clang 和 gcc 不一致
【发布时间】:2020-05-26 21:06:15
【问题描述】:

在 constexpr 成员函数的上下文中,clang 和 gcc 的行为有所不同,这里已经讨论过左值引用:stackoverflow/question/57779870

我将此扩展为对该类型的静态函数调用,该类型是从左值引用对象推导出来的,但以下内容在 clang 中仍然不起作用:

#include <type_traits>

// Dummy class with static constexpr member function
class MyClass {
public:
static constexpr bool check(int id){return true;}
};

template<int id, typename someT>
static constexpr bool doWithDeduction(someT& argument){
    return std::remove_reference_t<someT>::check(id);
}

// Replaced argument type by a dummy int type, argument is not used anyway
template<int id, typename someT>
static constexpr bool doWithDeduction(int& argument){
    return std::remove_reference_t<someT>::check(id);
}


// No function arguments! this works!
template<int id, typename someT>
static constexpr bool doSomething(){
    return std::remove_reference_t<someT>::check(id);
}

// wrapper to pass by ref
void wrap(MyClass& arg, int& i) {

    // works with gcc & clang
    static_assert(doSomething<1, decltype(arg)>(), "assert");

    // The following are not integral constexpr according to clang

    // This is what I want (type deduction for arg)
    static_assert(doWithDeduction<1>(arg), "assert");

    // Even when the type is not deduced but given here, this does not compile in clang
    static_assert(doWithDeduction<1, std::remove_reference_t<decltype(arg)>>(arg), "assert");

    // As soon as I pass somting(here int) as reference, clang complains about integral constant expressions
    static_assert(doWithDeduction<1, decltype(arg)>(i), "assert");
}

int main() {
    int i{1};
    MyClass myObject{};
    wrap(myObject, i);
}

这个例子也可以在这里找到:online_example godbolt 我正在使用 gcc 9.2.0 和 clang 9.0.1。 -std=c++17(或-std=c++14)

谁能解释一下,为什么连最后一个电话都不起作用?
哪个是期望的行为?

【问题讨论】:

    标签: c++ reference clang c++14 constexpr


    【解决方案1】:

    我对 gcc 在这里做了什么感到有点困惑。您的 static_asserts 未提供编译时值。 clang 拒绝代码是非常合理的,因为它似乎是错误的。我的意思是 - wrap 不是 constexpr 也不是 constexpr 值。你不能期望它的内容在编译时被评估。

    【讨论】:

      猜你喜欢
      • 2020-06-12
      • 1970-01-01
      • 2016-07-29
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      相关资源
      最近更新 更多