For example, it should be very helpful to equal compare a std::variant<T1, T2> with a T1 or T2. So far we can only compare with the same variant type.
下面的代码或在godbolt上的代码可以使用 gcc 和 MSVC 进行编译,但会因 clang 失败。我找不到标准中是否/哪里禁止它。我认为应该支持。
那么,clang 和 gcc/MSVC 谁的说法是正确的呢?
#include <type_traits>
void foo() {
static_assert(decltype([_=std::declval<int>()]() consteval noexcept { // clang error: declval() must not be used
if constexpr (std::is_integral<decltype(_)>::value) {
return std::bool_constant<true>();
} else {
return std::bool_constant<false>();
}
}())::value);
}
Run Code Online (Sandbox Code Playgroud)
该示例可以扩展为以下 3 种情况或在godbolt上:
因此,很明显,它在 lambda 主体中不合法,但在外部作为调用者参数是合法的。目前尚不清楚捕获列表中是否允许。
#include <type_traits>
auto foo_lambda_argument() {
return decltype([](auto _) noexcept {
return std::bool_constant<std::is_integral<decltype(_)>::value>();
}(std::declval<int>()))::value; // OK …Run Code Online (Sandbox Code Playgroud) #include <iostream>
#include <utility>
struct B {
template<typename T, std::enable_if_t<std::is_same<T, int>::value>* = nullptr>
void foo(T) {
std::cout<<"B::foo"<<std::endl;
}
};
struct D: B {
using B::foo;
template<typename T, std::enable_if_t<std::is_same<T, std::string>::value>* = nullptr>
void foo(T) {
std::cout<<"D::foo"<<std::endl;
}
};
int main() {
D d;
d.foo(2); // gcc: print "B::foo"; clang: compile error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
假设我们想foo()在派生类D中公开两个重载.gcc和Visual Studio编译并按照我的预期打印"B :: foo".但我得到一个与clang编译错误:
prog.cc:22:7: error: no matching member function for call to 'foo'
d.foo(2);
~~^~~
prog.cc:14:10: note: candidate template ignored: requirement 'std::is_same<int, std::string>::value' was …Run Code Online (Sandbox Code Playgroud) 假设我们有一个带有 2 个 xvalue 操作数的三元运算符。
struct A {
A() { std::cout<<"A ctor"<<std::endl; }
~A() { std::cout<<"A dtor"<<std::endl; }
A(A const&) { std::cout<<"A copy ctor"<<std::endl; }
A(A&&) { std::cout<<"A move ctor"<<std::endl; }
void foo() & { std::cout<<"A&.foo()"<<std::endl; }
void foo() const& { std::cout<<"A const&.foo()"<<std::endl; }
void foo() && { std::cout<<"A&&.foo()"<<std::endl; }
void foo() const&& { std::cout<<"A const&&.foo()"<<std::endl; }
};
int main()
{
A a;
A a2;
(true? static_cast<A&&>(a) : static_cast<A&&>(a2)).foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据cppreference条件运算符
4) 如果 E2 和 E3 是相同类型和相同值类别的左值,则结果具有相同类型和值类别,并且如果 E2 …
下面的简单代码或godbolt与 gcc、clang 和 Visual Studio 具有不同的结果。
auto foo1(int n) -> decltype(([n]() { return n+1; }()))
// gcc error: use of parameter outside function body before '+' token
{
return [n]() { return n+1; }();
}
auto foo2(int n) -> decltype(([&n]() { return n+1; }()))
// gcc error: use of parameter outside function body before '+' token
{
return [&n]() { return n+1; }();
}
auto foo3(int n) -> decltype(([&]() { return n+1; }()))
// gcc error: use of …Run Code Online (Sandbox Code Playgroud) struct B {
B(int) {}
B(B const&) {}
};
struct D: B {
using B::B;
};
int main(void) {
B b(5);
D d(b); // error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
c++14 在 12.9 [class.inhctor]/p3 中明确从继承的构造函数中排除复制/移动构造函数。
对于候选继承构造函数集中的每个非模板构造函数(除了没有参数的构造函数或具有单个参数的复制/移动构造函数之外),构造函数将隐式声明为具有相同的构造函数特征,除非存在用户声明的构造函数完整类中出现 using 声明的相同签名,或者构造函数将是该类的默认构造函数、复制构造函数或移动构造函数。
但我在c++17中找不到任何详细的描述。clang/gcc 显示基类的复制/移动构造函数不是继承的。有人可以提供标准中的解释吗?谢谢。
示例代码可以在下面或godbolt上找到。假设我们有 4 个班级:
S<T>:持有数据成员。
SCtor<T>:持有数据成员并具有模板构造函数。
SCtorMutable<T>:持有可变数据成员并具有模板构造函数。
SCtorDefault<T>:持有一个成员,有一个模板构造函数,有默认的复制/移动构造函数和默认的复制/移动赋值运算符。
所有编译器都同意这 4 个类是可以简单复制的。
如果有一个简单的包装类W<T>将上述任何一个类作为数据成员。包装类W<S...<T>>仍然是可简单复制的。
如果有另一个包装类WMutable<T>将上述类中的任何一个保存为可变数据成员。
WMutable<S...<T>>是可以简单复制的。WMutable<S<T>>是可以复制的。WMutable<SCtor...<T>>不是可简单复制构造的,因此也不是可简单复制的。WMutable<S<T>>是可以简单复制的。WMutable<SCtor...<T>>不是可简单复制构造的,而是可简单复制的。应该WMutable<T>是可以简单复制的吗?
#include <type_traits>
#include <utility>
template<typename T>
struct S {
T m_t;
};
template<typename T>
struct SCtor {
T m_t;
template<typename... U>
SCtor(U&&... u): m_t(std::forward<U>(u)...) {}
};
template<typename T>
struct SCtorMutable {
mutable T m_t;
template<typename... U> …Run Code Online (Sandbox Code Playgroud) c++ mutable copy-constructor language-lawyer trivially-copyable
下面或godbolt上的简单代码不能用 clang 编译,但可以用 gcc 和 Visual Studio 编译良好。
当 SFINAE 使用 clang、gcc 和 Visual Studio 失败时,不会评估 的尾随返回类型decltype(foo(t))。baz(T t)
但是,当 require 子句因 clang 失败时,仍会评估 的尾随返回decltype(foo(t))类型。bar(T t)当 gcc 和 Visual Studio 的 require 子句失败时,不会评估尾随返回类型。哪个编译器对此是正确的?
谢谢。
#include <utility>
#include <type_traits>
template<typename T>
auto foo(T) {
static_assert(std::is_integral<T>::value); // clang error: static_assert failed due to requirement 'std::is_integral<double>::value'
return 5;
}
template<typename T> requires std::is_integral<T>::value
auto bar(T t) -> decltype(foo(t)) {
return foo(t);
}
template<typename T> requires …Run Code Online (Sandbox Code Playgroud) c++20默认的比较运算符是一个非常方便的功能。但我发现如果该类有一个空的基类,它就没那么有用了。
默认运算符 <=> 通过连续比较 T 的基类(从左到右深度优先)和非静态成员(按声明顺序)子对象来计算 <=> 来执行字典比较,递归扩展数组成员(在下标递增的顺序),并在发现不相等的结果时提前停止
根据标准,SComparable如果没有运算符<=>,则不base会有运算符<=>。在我看来,为空类定义比较运算符是没有意义的。因此,默认的比较运算符不适用于具有空基类的类。
struct base {};
struct SComparable: base {
int m_n;
auto operator<=>(SComparable const&) const& = default; // default deleted, clang gives a warning
};
struct SNotComparable: base {
int m_n;
};
Run Code Online (Sandbox Code Playgroud)
如果我们迫切需要使用默认比较运算符,因此为空基类定义比较运算符base。另一个派生类SNotComparable由于其空基类而错误地变得具有可比性base。
struct base {
auto operator<=>(base const&) const& = default;
};
struct SComparable: base {
int m_n;
auto operator<=>(SComparable const&) const& = default;
};
struct SNotComparable: base { // SNotComparable is …Run Code Online (Sandbox Code Playgroud) 我尝试使用qi::uint_parser<int>()。但这是一样的qi::uint_。它们都匹配从0到的整数std::numeric_limits<unsigned int>::max()。
被qi::uint_parser<int>()设计成这个样子?我应该使用什么解析器来匹配从0到的整数范围std::numeric_limits<int>::max()?谢谢。
(1)假设我们要解析一个简单的递归块{}.
{
Some text.
{
{
Some more text.
}
Some Text again.
{}
}
}
Run Code Online (Sandbox Code Playgroud)
这个递归解析器非常简单.
x3::rule<struct idBlock1> const ruleBlock1{"Block1"};
auto const ruleBlock1_def =
x3::lit('{') >>
*(
ruleBlock1 |
(x3::char_ - x3::lit('}'))
) >>
x3::lit('}');
BOOST_SPIRIT_DEFINE(ruleBlock1)
Run Code Online (Sandbox Code Playgroud)
(2)然后块变得更复杂.它也可能被包围[].
{
Some text.
[
{
Some more text.
}
Some Text again.
[]
]
}
Run Code Online (Sandbox Code Playgroud)
我们需要在某处存放我们拥有的开放式支架.由于x3没有本地,我们可能会使用attribute(x3::_val).
x3::rule<struct idBlock2, char> const ruleBlock2{"Block2"};
auto const ruleBlock2_def = x3::rule<struct _, char>{} =
(
x3::lit('{')[([](auto& ctx){x3::_val(ctx)='}';})] |
x3::lit('[')[([](auto& ctx){x3::_val(ctx)=']';})]
) …Run Code Online (Sandbox Code Playgroud)