我一直在玩编译器优化和编译器资源管理器,并注意到 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 文字,这种情况仍然存在。
这会导致溢出。
为什么编译器不能在编译时推断出我的返回类型应该是双精度型?我会期望,因为 …
考虑这个简单的检查是否定义了(全局)函数:
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)
应该没有隐式转换,但我无法让它工作。
注意:概念方法的重点是摆脱旧的“检测模式”并进行简化。
为什么我可以这样做:
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) 我有一个关于编译时函数的问题。我知道 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) 有什么区别constexpr和consteval?
consteval int x1 = 2;
constexpr int x2 = 5;
Run Code Online (Sandbox Code Playgroud)
使用 constexpr 比使用 consteval 更好吗?
为什么用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 行的程序,其中包含一堆指针、一个长字符串常量等。
笔记:
autowrt constexprness的一般行为。该示例只是表明 GCC 不会将 x 视为constexpr我们没有明确告诉它。我想补充一下,你知道将来是否有删除它的意图吗?
是不是因为当您编写低级代码(例如,可能混合使用 C++ 和汇编程序)时,它不是一个妖魔化的语句?
在此链接中,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 库实现者关心的是什么?
我刚刚了解到我可以将 VS 2019 与 C++ 20 一起使用,并且我正在尝试使用它。我正在尝试使以下功能使用std::span,因为那样做data_size并且key_size将是多余的。
一切都好,除了*data和data++。它应该是什么?
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++ ×10
c++20 ×10
constexpr ×3
auto ×1
c++-concepts ×1
c++11 ×1
c++17 ×1
consteval ×1
constinit ×1
function ×1
g++ ×1
goto ×1
if-statement ×1
iterator ×1
std ×1
templates ×1
type-traits ×1
while-loop ×1