标签: c++20

无法找到 gcc13.2 发行说明中的​​更改或错误:具有不同约束的 template<typename> 的无效重新声明

几天前,我在 arch linux 上使用arm-none-eabi-gcc工具链时遇到了以下问题,它使用gcc13.2作为gcc版本,与我在Ubuntu中使用的工具链不同,我认为它会是某个版本所以我去了 gcc 发布页面阅读注释:https://gcc.gnu.org/gcc-13/changes.html,但是正如您所见,没有提到任何有关模板重新声明的内容

经过一些研究,我得出了这个可重现的例子:

// compiles fine under gcc 12.3

#include <concepts>
#include <type_traits>

 template<typename T>
 class Sensor{
   public:
    int read();
  };

template<typename T>
  requires std::is_integral_v<T>
int Sensor<T>::read(){
 return 1;
}

int main(){
 Sensor<int>  s;
 s.read();
}


//does not compile under gcc 13.2
#include <concepts>
#include <type_traits>

template<typename T>

class Sensor{
 public:
    int read();
};

template<typename T>
 requires std::is_integral_v<T>
int Sensor<T>::read(){
 return 1;
}

int main(){
 Sensor<int>  s;
 s.read();
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么在 12.3 版本中允许,但在 13.2 中不允许吗?另外我认为 …

c++ gcc compiler-bug c++20

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

不能在结构成员函数内使用默认的不等运算符

考虑使用默认比较稍微修改一下 cppreferenece.com 的示例:

struct Point
{
    int x;
    int y;

    auto operator<=>(const Point&) const = default;
    //bool operator!=(const Point&) const = default;

    bool isDifferent(const Point& another) const
    {
        // Fails without explicit operator !=
        return operator != (another);
    }

    bool isSame(const Point& another) const
    {
        // Always OK
        return operator == (another);
    }
};

int main()
{
    Point pt1{1, 1}, pt2{1, 2};
 
    std::cout << std::boolalpha
        << (pt1 == pt2) << ' '  // Always OK
        << (pt1 != …
Run Code Online (Sandbox Code Playgroud)

c++ spaceship-operator c++20

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

fmt::formatter 专业化不理解

我正在使用一种选择加入方法,可以通过自定义类的 std::cout 和 fmt::print 打印到控制台。为此,我创建了一个std::string to_string(const T& value)在一般情况下未定义的函数。专业课程应该:

  1. 专门化to_string(const MyType& t)
  2. 专门化struct printable< MyType >: public std::true_type{}

这将依次激活std::ostreamfmt::formatter自动专门针对每种printable类型。一个完整的例子是这样的:

#include <fmt/format.h>
#include <fmt/ostream.h>
#include <fmt/ranges.h>

#include <concepts>
#include <iostream>
#include <string>
#include <vector>

namespace common {

template <typename T>
std::string to_string(const T& value);

template <typename T>
struct printable : std::false_type {};

template <typename T>
constexpr bool printable_v = printable<T>::value;

}  // namespace common

template <typename T>
    requires(common::printable_v<T>)
auto& operator<<(std::ostream& os, const …
Run Code Online (Sandbox Code Playgroud)

c++ c++20 fmt

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

在 C++ 中使用 std::views::split 填充 std::vector 存在困难

std::vector我在尝试用 C++ 中的结果填充 a 时遇到问题std::views::split。具体来说,我可以成功地std::string从 的项构造 a std::ranges::split_view(如下面代码的第一个循环所示),但在尝试使用迭代器std::vector直接创建 a 时遇到困难。

// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>

int main()
{
    std::string rg{ "1, 2, 3, 1, 2, 3, 4, 5, 6 "};

    // Successful construction of std::string from std::ranges::split_view
    for (const auto& subrange : rg | std::views::split('3'))
    {
        std::string value(subrange.begin(), subrange.end());
        std::cout << value << '\n';
    }

    // Issue arises here when attempting to create std::vector
    auto parts …
Run Code Online (Sandbox Code Playgroud)

c++ split c++20 std-ranges

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

为什么将 std::string 初始化为 "" (通过 lambda)会崩溃?

为什么初始化std::stringto ""(通过 lambda)会崩溃?

这不会崩溃:

static std::string strTest2 = 
   [](){std::string * s = &strTest2; (*s) = "a"; return s->c_str();}();`
Run Code Online (Sandbox Code Playgroud)

这个技巧(首先将其初始化为非空,但预期的最终值为空)不会崩溃:

static std::string strTest3 =
   [](){std::string * s = &strTest3; (*s) = "b"; (*s) = ""; return s->c_str();}();
Run Code Online (Sandbox Code Playgroud)

在这里崩溃了(*s) = ""。是因为它是空字符串吗?很特别吗?std::string分配给 时是否未构造/初始化""

static std::string strTest1 =
   [](){std::string * s = &strTest1; (*s) = ""; return s->c_str();}();`
Run Code Online (Sandbox Code Playgroud)

c++ lambda initialization c++20 selfinitialization

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

C++ 函数调用概念不明确

我有一个 C++ 宏,我想用它来调用一个重载的函数模板。我希望这些函数模板之一仅接受浮点值,而另一个函数模板将接受其他所有内容。

以下是我使用 C++ 20 在https://cpp.sh/中运行的代码:

#include <iostream>
#include <string>
#include <vector>
#include <type_traits>
#include <concepts>

template< typename T>
concept NotFloatingPoint = requires
{
    !std::is_same_v<T, double> || !std::is_same_v<T, float>;
};

template< NotFloatingPoint T, NotFloatingPoint U, bool isDistanceType_ = false >
void ProcConstantConfigForce( T& value_ )
{
    std::cout << "Inside ProcConstantConfigForce()\n";
    std::cout << value_;
}

template< typename T>
concept FloatingPoint = requires
{
    std::is_same_v<T, double> || std::is_same_v<T, float>;
};

template< FloatingPoint T, FloatingPoint U, bool isDistanceType_ = false > …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++-concepts c++20

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

下面的代码无法编译.也许是因为带有std = c ++ 2a的GCC仍然没有与最新的草案完全一致

[class.mem]/6:

一个完整的类的上下文是一个

(6.1)函数体,(6.2)默认参数,(6.3) noexcept-specifier([except.spec]),(6.4)合同条件,或(6.5)默认成员初始化程序

在类的成员规范内.[注意:如果嵌套类在封闭类的成员规范中定义,则嵌套类的完整类上下文也是任何封闭类的完整类上下文. - 结束说明]

该段落在草案中引入了拉动请求#2231.

据我所知,根据上面的注释,下面的代码应该编译.但事实并非如此.我假设GCC编译器仍然不是最新的草案.我是否正确,或者我对此笔记的理解是否正确?

struct A {
    int i = 1;
    struct B { 
        int j = 2;
        int f() {
            return i + j;
        }
    };
};
Run Code Online (Sandbox Code Playgroud)

哪个失败了:

source>: In member function 'int A::B::f()':
<source>:6:20: error: invalid use of non-static data member 'A::i'
    6 |             return i + j;
      |                    ^
<source>:2:9: note: declared here
    2 |     int i = 1;
      | …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++20

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

C ++自动用于类型和非类型模板

在c ++ 17中,template <auto>允许使用任意类型参数声明模板。通过部分灵感这个问题,这将是非常有用的的扩展template <auto>来捕捉类型和无类型模板参数,并且还允许它的可变参数版本。

在下一个c ++ 20版本中是否有计划进行此类扩展?template<auto... X>使用X任何类型或非类型模板参数的语法,是否存在一些基本问题?

c++ templates language-lawyer c++20

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

来自不同翻译单元的约束函数可以干扰吗?

我试图探究某个功能的含义,inline并偶然发现了这个问题。考虑这个小程序(demo):

/* ---------- main.cpp ---------- */
void other();

constexpr int get()
{
    return 3;
}

int main() 
{
    std::cout << get() << std::endl;
    other();
}

/* ---------- other.cpp ---------- */
constexpr int get()
{
    return 4;
}

void other()
{
    std::cout << get() << std::endl;
}

Run Code Online (Sandbox Code Playgroud)

在不进行优化的情况下进行编译时,该程序将产生以下输出:

3
3
Run Code Online (Sandbox Code Playgroud)

可能不是我们想要的,但是至少我可以解释一下。

  1. 不需要编译器constexpr在编译时计算函数结果,因此决定将其推迟到运行时。
  2. constexpr 在功能上意味着 inline
  3. 我们的get()功能碰巧有不同的实现
  4. 我们没有将get()函数声明为静态
  5. 链接器只能选择该get()功能的一种实现

碰巧的是,链接器get()从中选择main.cpp,返回了3。

现在到我不了解的部分。我只是get()功能从更改constexpr为 …

c++ one-definition-rule constexpr c++20 consteval

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

编译时评估代码中的重言式是否保证被执行/优化掉?

编译器是否保证评估环境constexpr"tautologies"(例如始终truefalse分别)的布尔表达式constexpr

最小示例/说明

例如,在以下代码片段(在标有 的行(1))中,我在constexpr环境中调用了一个函数,我打算在non-constexpr传递函数时导致编译时错误。至少我使用的编译器 ( g++-10.0) 是这样做的,即使它也可以意识到表达式总是true不计算它。我问这个问题的原因是 - 据我所知 - 在非 constepxr 上下文中,像这样的表达式i >= std::numeric_limits<int>::min()被优化trueint i.

#include <limits>
constexpr int example_function() { return 1;}
constexpr bool compileTimeErrorDesired = example_function() || true; // (1)
Run Code Online (Sandbox Code Playgroud)

应用实例

如果(1) 保证in 的行为,则可以在 aconcept中使用它,以执行不同的代码,具体取决于是否可以在编译时评估作为模板参数提供的函数。我实现了一个非常短的 ( 7 lines-of-code) 示例,它在编译器资源管理器中完全做到这一点。

如果使用非 constexpr 函数调用,行 (1) …

c++ language-lawyer constexpr c++-concepts c++20

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