几天前,我在 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 中不允许吗?另外我认为 …
考虑使用默认比较稍微修改一下 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) 我正在使用一种选择加入方法,可以通过自定义类的 std::cout 和 fmt::print 打印到控制台。为此,我创建了一个std::string to_string(const T& value)在一般情况下未定义的函数。专业课程应该:
to_string(const MyType& t)struct printable< MyType >: public std::true_type{}这将依次激活std::ostream并 fmt::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) 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) 为什么初始化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++ 宏,我想用它来调用一个重载的函数模板。我希望这些函数模板之一仅接受浮点值,而另一个函数模板将接受其他所有内容。
以下是我使用 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) 一个完整的类的上下文是一个
(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 ++ 17中,template <auto>允许使用任意类型参数声明模板。通过部分灵感这个问题,这将是非常有用的的扩展template <auto>来捕捉类型和无类型模板参数,并且还允许它的可变参数版本。
在下一个c ++ 20版本中是否有计划进行此类扩展?template<auto... X>使用X任何类型或非类型模板参数的语法,是否存在一些基本问题?
我试图探究某个功能的含义,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)
可能不是我们想要的,但是至少我可以解释一下。
constexpr在编译时计算函数结果,因此决定将其推迟到运行时。constexpr 在功能上意味着 inlineget()功能碰巧有不同的实现get()函数声明为静态get()功能的一种实现碰巧的是,链接器get()从中选择main.cpp,返回了3。
现在到我不了解的部分。我只是将get()功能从更改constexpr为 …
编译器是否保证评估环境constexpr中"tautologies"(例如始终true或false分别)的布尔表达式constexpr?
例如,在以下代码片段(在标有 的行(1))中,我在constexpr环境中调用了一个函数,我打算在non-constexpr传递函数时导致编译时错误。至少我使用的编译器 ( g++-10.0) 是这样做的,即使它也可以意识到表达式总是true不计算它。我问这个问题的原因是 - 据我所知 - 在非 constepxr 上下文中,像这样的表达式i >= std::numeric_limits<int>::min()被优化true为int 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++ ×10
c++20 ×10
c++-concepts ×2
constexpr ×2
templates ×2
compiler-bug ×1
consteval ×1
fmt ×1
gcc ×1
lambda ×1
split ×1
std-ranges ×1