标签: c++20

为什么 std::vector::iterator 不是连续迭代器?

按照cppref页面std::vector

iterator 传统随机访问迭代器

同样来自另一个cppref 页面

以下标准库类型是LegacyContiguousIterators

vector::iterator 对于 bool 以外的 value_type。

哪个是正确的?

c++ iterator type-traits c++-concepts c++20

0
推荐指数
1
解决办法
160
查看次数

使用 constexpr + auto 作为返回和参数类型的奇怪类型推导

我一直在玩编译器优化和编译器资源管理器,并注意到 g++ 9.3(本地测试)中的以下缺点。该问题似乎在 g++ 10.1(在编译器资源管理器上测试)中仍然存在。我正在使用

请注意以下代码:

#include <iostream>
#include <iomanip>

constexpr auto fib( auto x )
{
    if( x == 0 )
        return 0;
    else if( x == 1 )
        return 1;
    else
        return fib( x - 1 ) + fib( x - 2 );
}

int main( int argc, char * argv[] )
{
    std::cerr << std::setprecision(10) << fib( 47.l );
}
Run Code Online (Sandbox Code Playgroud)

编译器资源管理器链接在这里

我知道如果我放了 47,模板参数推导会推导出 function int foo( int x ),但是即使我传递一个 long double 文字,这种情况仍然存在。

这会导致溢出。

为什么编译器不能在编译时推断出我的返回类型应该是双精度型?我会期望,因为 …

c++ g++ compiler-optimization c++20

0
推荐指数
1
解决办法
69
查看次数

检查(全局)函数是否存在但不允许隐式转换

考虑这个简单的检查是否定义了(全局)函数:

template <typename T>
concept has_f = requires ( const T& t ) { Function( t ); };
// later use in MyClass<T>:
if constexpr ( has_f<T> ) Function( value );
Run Code Online (Sandbox Code Playgroud)

不幸的是,这允许隐式转换。这显然是一个很大的混乱风险。

问题:如何检查 Function( const T& t ) 是否“显式”存在?

就像是

if constexpr ( std::is_same_v<decltype( Function( t ) ), void> )
Run Code Online (Sandbox Code Playgroud)

应该没有隐式转换,但我无法让它工作。

注意:概念方法的重点是摆脱旧的“检测模式”并进行简化。

c++ templates function implicit-conversion c++20

0
推荐指数
1
解决办法
135
查看次数

为什么我们可以在 if 循环中使用分号,而在 while 循环中不能使用分号

为什么我可以这样做:

if (int result=getValue(); result > 100) {
}
Run Code Online (Sandbox Code Playgroud)

但不能这样做:

while (int result=getValue(); result > 100) {
}
Run Code Online (Sandbox Code Playgroud)

为什么要歧视while?条件就是条件。为什么while不能像ifcan那样评价它?

为了使用 实现所需的行为while,我必须以这种方式实现它:

int result = getValue();
while (result > 100) {
    //do something
    result = getValue();
}
Run Code Online (Sandbox Code Playgroud)

c++ if-statement while-loop c++17 c++20

0
推荐指数
1
解决办法
183
查看次数

使用 constinit const 时 static_assert 失败。constinit、constinit const、constexpr、const、非常量变量中的混淆

我有一个关于编译时函数的问题。我知道 static_assert 应该只适用于可以在编译时评估/计算的类型。所以它不适用于 std::string (然而,gcc10 中不支持 constexpr std::string)但可以使用 std::array(当我在编译时知道大小时)。我正在观看 Jason Turner 的 C++ Weekly,所以这个片段来自这一集https://www.youtube.com/watch?v=INn3xa4pMfg

代码在这里:https : //godbolt.org/z/e3WPTP

#include <array>
#include <algorithm>

template<typename Key, typename Value, std::size_t Size>
struct Map final
{
    std::array<std::pair<Key, Value>, Size> _data;

    [[nodiscard]] constexpr Value getMappedKey(const Key& aKey) const
    {
        const auto mapIterator = std::ranges::find_if(_data, [&aKey](const auto& pair){ return pair.first == aKey;});

        if(mapIterator != _data.end())
        {
            return mapIterator->second;
        }
        else
        {
            throw std::out_of_range("Key is not in the map");
        }
    }
};

enum class OurEnum …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++20 constinit

0
推荐指数
1
解决办法
153
查看次数

变量上的 consteval 与 constexpr

有什么区别constexprconsteval

 consteval int x1 = 2;
 constexpr int x2 = 5;
Run Code Online (Sandbox Code Playgroud)

使用 constexpr 比使用 consteval 更好吗?

c++ constexpr c++11 c++20 consteval

0
推荐指数
1
解决办法
518
查看次数

为什么`auto` 不采用其初始化表达式的constexpr'ness?

为什么用auto关键字定义变量不带有constexpr用于初始化它的表达式的“性质”?


例如,请考虑以下代码:

#include <string_view>

constexpr std::string_view f() { return "hello"; }

static constexpr std::string_view g() {
    constexpr auto x = f(); // (*)
    return x.substr(1, 3);
}

int foo() { return g().length(); }
Run Code Online (Sandbox Code Playgroud)

使用 GCC 10.2 和--std=c++20 -fsanitize=undefined -O3编译为:

foo():
        mov     eax, 3
        ret
Run Code Online (Sandbox Code Playgroud)

但是,如果我们删除 (*) 行上的 constexpr,我们将得到一个 27 行的程序,其中包含一堆指针、一个长字符串常量等。

笔记:

  • 我将此问题标记为 C++20,但我没有理由相信这种行为与 C++11 不同。
  • 这个问题与示例无关,而是关于autowrt constexprness的一般行为。该示例只是表明 GCC 不会将 x 视为constexpr我们没有明确告诉它。

c++ type-inference constexpr auto c++20

0
推荐指数
1
解决办法
134
查看次数

除了向后兼容之外,还有什么理由让 C++20 仍然将 goto 作为语句包含在内?

我想补充一下,你知道将来是否有删除它的意图吗?

是不是因为当您编写低级代码(例如,可能混合使用 C++ 和汇编程序)时,它不是一个妖魔化的语句?

c++ goto c++20

0
推荐指数
2
解决办法
186
查看次数

c++ std 库实现者在为 remove_cvref 模板添加特化时警告未定义行为的关注点是什么?

在此链接中,https://en.cppreference.com/w/cpp/types/remove_cvref,它指出

template< class T >
struct remove_cvref;
Run Code Online (Sandbox Code Playgroud)

如果类型 T 是引用类型,则提供成员 typedef type,它是 T 引用的类型,并删除了其最顶层的 cv 限定符。否则,类型是 T 并删除其最顶层的 cv 限定符。

添加专业化的程序的行为remove_cvref是未定义的。

在这种情况下,c++ std 库实现者关心的是什么?

c++ c++20

0
推荐指数
1
解决办法
81
查看次数

使函数使用 std::span 而不是旧方法

我刚刚了解到我可以将 VS 2019 与 C++ 20 一起使用,并且我正在尝试使用它。我正在尝试使以下功能使用std::span,因为那样做data_size并且key_size将是多余的。

一切都好,除了*datadata++。它应该是什么?

int rc4(rc4_context* context, const std::uint8_t* data, const std::size_t data_size, const std::uint8_t* key, const std::size_t key_size, std::uint8_t* output)
{
    std::uint32_t i, j;

    // Check parameters
    if (!context || !key)
        return ERROR_INVALID_PARAMETER;

    // Clear context
    context->i = 0;
    context->j = 0;

    // Initialize the S array with identity permutation
    for (i = 0; i < 256; i++)
    {
        context->s[i] = static_cast<std::uint8_t>(i);
    }

    // S …
Run Code Online (Sandbox Code Playgroud)

c++ std c++20

0
推荐指数
1
解决办法
72
查看次数