小编flo*_*tan的帖子

如果 lambda 中带有 static_assert 的 constexpr,哪个编译器是正确的?

当我们想在 astatic_assert中使用 a 时,if constexpr我们必须使条件依赖于某个模板参数。有趣的是,当代码包含在 lambda 中时,gcc 和 clang 不同意。

以下代码使用 gcc 进行编译,但 clang 会触发断言,即使if constexpr不能为真。

#include <utility>

template<typename T> constexpr std::false_type False;

template<typename T>
void foo() {

    auto f = [](auto x) {
        constexpr int val = decltype(x)::value;
        if constexpr(val < 0) {
            static_assert(False<T>, "AAA");
        }
    };

    f(std::integral_constant<int, 1>{});
}

int main() {
    foo<int>();
}
Run Code Online (Sandbox Code Playgroud)

现场示例在这里

它可以很容易地通过用固定False<T>通过False<decltype(x)>

所以问题是:哪个编译器是正确的?我认为 gcc 是正确的,因为 中的条件static_assert取决于T,但我不确定。

c++ templates static-assert language-lawyer c++17

13
推荐指数
2
解决办法
445
查看次数

在 C++20 常量表达式中是否允许比较动态分配对象的地址?

只要内存不泄漏,C++20 就允许在 constexpr 函数中分配堆。然而 GCC 和 Clang 在比较两个动态分配对象的地址是否是一个常量表达式的问题上存在分歧。

以下代码段可以用 Clang 编译,但不能用 gcc 编译。

constexpr bool foo() {
    int* a = new int(4);
    int* b = new int(4);
    bool result = a == b;
    delete a;
    delete b;
    return result;
}

constexpr bool x = foo(); // GCC:  error: '(((int*)(& heap deleted)) == ((int*)(& heap deleted)))' is not a constant expression
Run Code Online (Sandbox Code Playgroud)

以下在两个编译器上都可以正常工作

constexpr bool foo2() {
    int a = 4;
    int b = 5;
    bool result = &a ==  &b;

    return …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer constexpr c++20

10
推荐指数
1
解决办法
150
查看次数

模板类型别名可见性编译器不一致

以下示例使用 gcc 编译,但不使用 clang 编译。哪个编译器是正确的,为什么?

#include <utility>

struct Foo {

private:
    
    template<typename T>
    static int f();

public:

    template<typename U>
    using T = decltype(f<U>());

};


int main () {

    static_assert(std::is_same_v<Foo::T<float>, int>);
}
Run Code Online (Sandbox Code Playgroud)

Clang 抱怨说'f' is a private member of 'Foo'。我认为这是不正确的,因为f是从内部访问的Foo,因此应该是可见的。有趣的是,如果T不是模板,它也能工作。

现场代码在这里

c++ templates language-lawyer

8
推荐指数
1
解决办法
63
查看次数

理解用户定义的字符串文字编译器错误“.. is not a variable”

我想知道这两个字符串 UDL 之间的区别。虽然第一个编译得很好,但第二个出现错误。

唯一不同的是,Literal1使用std::array作为存储,同时Literal2使用const char *

我可以轻松地Literal2显式构造一个,但是一旦我尝试使用 UDL 编译就会失败,并且'"123"' is not a valid template argument of type 'const char*' because '"123"' is not a variable. 有趣的是,如果我不在p构造函数中初始化,它也可以很好地编译。

template < size_t size >
struct Literal1 : std::array<char,size>
{
    constexpr Literal1(char const (&str)[size+1]) { for (size_t ii = 0; ii < size; ++ii) (*this)[ii] = str[ii]; }
};

template < size_t size > Literal1(char const (&str)[size]) -> Literal1<size-1>;
template …
Run Code Online (Sandbox Code Playgroud)

c++ templates language-lawyer user-defined-literals c++20

6
推荐指数
0
解决办法
66
查看次数

如果 Rest... 为空, template&lt;typename T&gt; 是否与 template&lt;typename T, typename... Rest&gt; 相同?

我试图在 CRTP 类中创建一个“转换复制构造函数”,如下所示: template struct Base;

template<typename Derived>
struct Base;

template<template<typename, typename...> class DerivedType, typename T, typename... Rest >
struct Base<DerivedType<T, Rest...>> {

    Base() = default;

    template<typename T2, typename... Rest2>
    Base(const Base<DerivedType<T2, Rest2...>>& other)  {
    }

};

template<typename T>
struct Child : Base<Child<T>> {

    using MyBase = Base<Child<T>>;

    Child() = default;    

    template<typename T2>
    Child(const Child<T2>& other) : MyBase(other) {}

};

int main() {

    Child<int> cti;
    Child<float> ctf = cti;

}
Run Code Online (Sandbox Code Playgroud)

该代码可以使用 never gcc 版本进行编译,但不能使用其他编译器进行编译。他们拒绝它,因为模板参数太多:

<source>:11:21: error: too many template arguments …
Run Code Online (Sandbox Code Playgroud)

c++ templates language-lawyer variadic-templates

5
推荐指数
0
解决办法
191
查看次数

Clang 15 和 C++20 `std::views::filter` 错误

我想知道为什么这个代码不能用 clang 15 编译,即使范围库在编译器支持页面上的 clang 15 中被标记为完全支持?它确实使用 g++12 进行编译,即使支持仅标记为部分,并且它使用 clang trunk 进行编译。

#include <ranges>
#include <vector>

int main() {
    std::vector x{1,2,3,4};
    auto y = x | std::views::filter([](auto i){ return i <2;});
}
Run Code Online (Sandbox Code Playgroud)

代码是否错误?如果是的话,有没有办法解决这个错误,直到 clang 16 发布为止。我猜范围-v3 会起作用,但也许有人知道如何仅使用标准库来修复它。

有趣的是,我在使用-stdlib=libstdc++and时遇到了不同的错误-stdlib=libc++

  • libstdc++:error: invalid operands to binary expression ('std::vector<int>' and '_Partial<std::ranges::views::_Filter, decay_t<(lambda at <source>:7:37)>>' (aka '_Partial<std::ranges::views::_Filter, (lambda at <source>:7:37)>'))
  • libc++:error: no member named 'views' in namespace 'std'

编译器资源管理器。

c++ compiler-errors clang c++20

5
推荐指数
1
解决办法
2100
查看次数