我<=>在C ++ 20中使用新的宇宙飞船运算符遇到一种奇怪的行为。我正在将Visual Studio 2019编译器与一起使用/std:c++latest。
这段代码可以正常编译:
#include <compare>
struct X
{
int Dummy = 0;
auto operator<=>(const X&) const = default; // Default implementation
};
int main()
{
X a, b;
a == b; // OK!
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我将X更改为:
struct X
{
int Dummy = 0;
auto operator<=>(const X& other) const
{
return Dummy <=> other.Dummy;
}
};
Run Code Online (Sandbox Code Playgroud)
我收到以下编译器错误:
error C2676: binary '==': 'X' does not define this operator or a conversion to …
我一直在寻找这个,我似乎无法找到一个直接的答案.一些消息来源说这是不可能的,但这只会给我带来更多问题,我将在下面进一步解释.
所以情况就是这样.假设我有一个带有如下选择函数的自定义容器类(这只是一个例子):
template <typename T>
class Container {
public:
// ...
Container<T> select(bool (*condition)(const T&)) const;
// ...
};
Run Code Online (Sandbox Code Playgroud)
如您所见,该select函数采用指向条件函数的指针.这是一个定义应选择哪些项目的函数.因此,使用此示例将类似于:
bool zero_selector(const int& element) {
return (element == 0); // Selects all elements that are zero
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我有一个容器填充,比方说s = { 1, 1, 0, 0, 1, 0, 1, 0 },我可以选择这些只包含零的子集:
t = s.select(&zero_selector); // t = { 0, 0, 0, 0 }
Run Code Online (Sandbox Code Playgroud)
如你所见,这有点笨重.Lambda函数会使这更加优雅,所以我可以使用(我不确定这是否是正确的语法),例如:
t = s.select([&] (int x) -> bool { return (x == 0); …Run Code Online (Sandbox Code Playgroud) 问题非常简单.为清楚起见,请考虑以下示例:
// Note that none of the class have any data members
// Or if they do have data members, they're of equal size, type, and quantity
class Foo {
public:
void foo1();
void foo2();
// 96 other methods ...
void foo99();
};
class Bar {
public:
// Only one method
void bar();
};
class Derived1 : public Foo { };
class Derived2 : public Bar { };
int main() {
Foo f;
Bar b;
Derived1 d1;
Derived2 d2;
return …Run Code Online (Sandbox Code Playgroud) 我一直在探索C++ 中Move Constructors的可能性,我想知道在下面的例子中有哪些方法可以利用这个功能.考虑以下代码:
template<unsigned int N>
class Foo {
public:
Foo() {
for (int i = 0; i < N; ++i) _nums[i] = 0;
}
Foo(const Foo<N>& other) {
for (int i = 0; i < N; ++i) _nums[i] = other._nums[i];
}
Foo(Foo<N>&& other) {
// ??? How can we take advantage of move constructors here?
}
// ... other methods and members
virtual ~Foo() { /* no action required */ }
private:
int _nums[N];
};
Foo<5> bar() …Run Code Online (Sandbox Code Playgroud) 问题几乎在标题中.根据C++ Reference,std::endl实际上是一个函数.看看它的声明<iostream>,这可以得到验证.
但是,当您使用时std::endl,您不使用std::endl().相反,你使用:
std::cout << "Foo" << std::endl;
Run Code Online (Sandbox Code Playgroud)
实际上,如果您使用std::endl(),编译器需要更多参数,如上面的链接所示.
有人会解释这个吗?有什么特别之处std::endl?我们可以在调用时实现不需要任何括号的函数吗?
在Visual Studio中,如果按住CTRL并单击单词,则会选择整个单词.如果拖动,它会逐字选择文本.
我发现Visual Studio中的这个功能非常有用,当我复制粘贴小的代码位,因为我只能坚持下去CTRL,选择的话,按C,X或V左右移动的东西.
在VS Code中,您无法执行此操作.相反,CTRL+ CLICK必然会"转到定义".
有没有办法在这种情况下匹配VS Code与Visual Studio的行为?
我正在努力了解它的用处static_assert,我想知道它是否可以帮助我执行设计,如果是,那么如何.
我有一个通用的模板类,它在另一个模板类中隐藏它自己的实现,这个类是基于模板类型的大小而部分专用的.以下是此设计的简要概述:
template <class T, size_t S = sizeof(T)>
struct Helper;
template <class T>
struct Helper<T, sizeof(long)>
{
static T bar();
};
// ... other specializations ...
template <class T>
class Foo
{
public:
T bar()
{
return Helper<T>::bar();
}
};
Run Code Online (Sandbox Code Playgroud)
美孚如果尺寸仅支持T由一个专业化的支持助手.例如,Foo<long>并且Foo<unsigned long>都受支持.但是,假设用户尝试构造一个Foo<bool>.通常,这会产生错误,因为没有定义Helper for的特化bool,这是预期的行为.
static_assert在此设计中是否有任何方法可以为此界面的用户提供更多有用的错误?
此外,我还想限制用户使用特定类型,即使大小可能是正确的.例如,Foo<float>不应该被允许.现在,我知道强制执行此操作的唯一方法是通过文档中的大胆注释.:)
在类层次结构的设计中,我使用了一个抽象基类,它声明了派生类将实现的各种方法.从某种意义上说,基类与C++中的接口一样接近.但是,有一个具体问题.考虑下面的代码声明我们的接口类:
class Interface {
public:
virtual Interface method() = 0;
};
class Implementation : public Interface {
public:
virtual Implementation method() { /* ... */ }
};
Run Code Online (Sandbox Code Playgroud)
当然,这不会编译,因为你不能在C++中返回一个抽象类.为了解决这个问题,我使用以下解决方案:
template <class T>
class Interface {
public:
virtual T method() = 0;
};
class Implementation : public Interface<Implementation> {
public:
virtual Implementation method() { /* ... */ }
};
Run Code Online (Sandbox Code Playgroud)
这个解决方案很有效,但是,对我来说,它看起来并不优雅,因为文本的冗余位将是接口的参数.如果你们能指出我们在设计方面的任何其他技术问题,我会很高兴,但这是我唯一关心的问题.
有没有办法摆脱冗余模板参数?可能使用宏?
注意:有问题的方法必须返回一个实例.我知道如果method()返回指针或引用,就没有问题.
我正在使用自定义序列化程序创建自定义,模板繁重的序列化库。我希望能够Serializer使用SFINAE在我的库中检测和强制执行该概念(我无法访问具有概念支持的C ++ 20编译器):
class CustomSerializer
{
static T Serialize(S);
static S Deserialize(T);
};
Run Code Online (Sandbox Code Playgroud)
这里的想法是的输入类型Serialize必须等于的输出类型Deserialize,反之亦然
这可能吗?如果是这样,怎么办?
我尝试研究std::invoke_result_t,但随后需要提供参数类型。但是Deserialize的参数类型是Serialize的调用结果,并且要获取Serialize的调用结果,...
我希望您在这里看到圆形图案,这使我想知道是否有可能。
因此,经过大量搜索我的问题的答案后,我终于放弃了我的Google技能.
我有一个基类Base和一个派生类Derived.我想在Derived类中使用一个类重写Base类中的类型.这是一个例子:
class Apple {
public:
Apple() { }
// ...
};
class Orange {
public:
Orange() { }
// ...
};
class Base {
public:
typedef Apple fruit;
// ...
virtual fruit func() { return Apple(); }
};
class Derived : public Base {
public:
typedef Orange fruit;
// ...
fruit func() override { return Orange(); } // <-- Error C2555!
};
Run Code Online (Sandbox Code Playgroud)
这段代码不起作用,它给出了一个
C2555 error ('Derived::func': overriding virtual function return type …Run Code Online (Sandbox Code Playgroud) c++ ×9
inheritance ×2
c++11 ×1
c++20 ×1
class ×1
lambda ×1
methods ×1
oop ×1
overriding ×1
sfinae ×1
std ×1
templates ×1
type-traits ×1
typedef ×1
virtual ×1