我正在尝试使用CRTP实现Clonable类.但是,我需要具有纯虚拟克隆方法的抽象类,由子类重写.为了实现这一点,我需要克隆函数来返回协变返回类型.我在下面制作了这段代码,编译器向我大喊这个错误:
main.cpp:12:5: error: return type of virtual function 'clone' is not covariant with the return type of the function it overrides ('B *' is not derived from 'AbstractClonable *')
Run Code Online (Sandbox Code Playgroud)
类'B'似乎是AbstractClonable的子类,甚至是双向的!我怎么解决这个问题?非常感谢你.我尝试使用clang 3.6和GCC 4.9.2
struct AbstractClonable {
virtual AbstractClonable* clone() const = 0;
};
template<typename T>
struct Clonable : virtual AbstractClonable {
T* clone() const override {
return new T{*dynamic_cast<const T*>(this)};
}
};
struct A : virtual AbstractClonable {
};
struct B : A, Clonable<B> {
};
Run Code Online (Sandbox Code Playgroud) 我最近在c ++ 11中使用过一些代码.这段代码在GCC和Clang中运行良好,我在我的项目中广泛使用它.现在,我需要让它在MSVC中运行.我需要的所有c ++ 11功能都标记为是.但是,这个代码示例只是拒绝构建.我试图修复错误,但我还没有找到解决方案.这是样本:
#include <functional>
#include <iostream>
#include <type_traits>
template<typename T>
struct Provider final {
Provider() = delete;
Provider(const Provider& other) : _callback{ other._callback } {}
Provider(Provider&& other) : _callback{ std::move(other._callback) } {}
Provider& operator=(Provider&& other) {
std::swap(other._callback, _callback);
return *this;
}
Provider& operator=(const Provider& other) {
_callback = other._callback;
return *this;
}
template<typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type, typename = typename std::enable_if<!std::is_same<U, T>::value>::type>
Provider<T>& operator=(Provider<U>&& other) {
std::swap(other._callback, _callback);
return *this;
}
template<typename U, typename = …Run Code Online (Sandbox Code Playgroud) 我的模板结构的静态constexpr成员遇到了一些问题.代码编译但我得到链接错误.这是我正在尝试做的事情:
template<int n>
struct Test {
static constexpr auto invoke = make_tuple(2, "test", 3.4);
};
template<typename T>
void test(T&& t) {
cout << t << endl;
}
int main() {
test(get<0>(Test<2>::invoke));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我有链接错误,所以我尝试了这个:
template<int n>
struct Test {
static constexpr auto invoke = make_tuple(2, "test", 3.4);
};
// declare it outside the class
template<int n>
constexpr decltype(Test<n>::invoke) Test<n>::invoke;
template<typename T>
void test(T&& t) {
cout << t << endl;
}
int main() {
test(get<0>(Test<2>::invoke));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但相反,我得到了这个奇怪的错误: …
在过去的十年或二十年中使用C#之后,我的C++变得有点生疏了.
如果我有以下内容:
class CBase
{
public:
CBase(LPCTSTR pszArg1, LPCTSTR pszArg2, LPCTSTR pszArg3);
virtual ~CBase();
// Etc...
};
class CDerived : CBase
{
// Etc...
};
Run Code Online (Sandbox Code Playgroud)
看来我无法创建一个实例CDerived.
没有构造函数"CDerived :: CDerived"的实例与参数列表匹配
我知道我可以显式创建派生构造函数:
CDerived::CDerived(LPCTSTR pszArg1, LPCTSTR pszArg2, LPCTSTR pszArg3)
: CBase(pszArg1, pszArg2, pszArg3)
{
}
Run Code Online (Sandbox Code Playgroud)
但这似乎是很多打字,特别是如果我打算从基类派生许多类.
基类仍然需要这些或那些参数.有没有办法不必为每个派生类重写这个参数,或者"暴露"基础构造函数,或者我必须像以前一样完全按照这样做?
我用GCC编译了一些代码-Wall并-Wextra启用了.此代码生成警告:
struct A { A(int) {} };
struct B {};
struct C : A, B {};
int main() {
(void) C{1};
}
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)main.cpp: In function 'int main()': main.cpp:11:15: warning: missing initializer for member 'C::<anonymous>' [-Wmissing-field-initializers] (void) C{1}; ^
我应该担心吗?这是GCC输出此警告的错误吗?似乎我没有要初始化的字段,也没有缺少参数.
In the C++14 standard, the std::integral_constant template is defined as follows:
template <class T, T v>
struct integral_constant {
static constexpr T value = v;
typedef T value_type;
typedef integral_constant<T,v> type;
constexpr operator value_type() const noexcept { return value; }
constexpr value_type operator()() const noexcept { return value; }
};
Run Code Online (Sandbox Code Playgroud)
It doesn't say whether there's a corresponding out-of-line definition for the static data member, i.e.,
template <class T, T v>
constexpr T integral_constant<T, v>::value;
Run Code Online (Sandbox Code Playgroud)
I looked through the standard …
简短问题:
是否有为什么C ++ STL实现使用一个原因vector_base结构/类(到手柄资源和分配器),为基类的std::vector,而不是使用组合物?
较长版本:
在提高我对C ++的了解的“任务”中,我一直在尝试重新实现一个Vector大多数是std::合规的类。我想我已经足够了解为什么使用分配器明智,为什么您实际上希望将所有内存处理放在单独的类/结构(RAII等)中,但我看不到为什么我们std::vector要从中继承类,而不是将其作为私人成员。
例如,LLVM和gcc都使用继承。另一方面,我发现构造函数和赋值运算符(尤其是move-types)使用合成更容易处理。
我只是公开我对语言的肤浅知识吗?
举例来说,我搜索了一本教科书,发现Stroustroup的书与他的2013年的“ C ++编程语言,第四版”对标准的“模拟重新实现”有不同的版本(只是让我更加困惑!)。使用构图及其2014年的“编程:原理与实践,第二版”。使用继承!
任何人都可以帮助我阐明一些想法吗?
假设我有一个定义了复制和移动赋值运算符的对象。当我写下这个:
Object a(/*parameters 1*/);
/* some code */
a = Object(/*parameters 2*/);
Run Code Online (Sandbox Code Playgroud)
第三行很可能会调用移动赋值运算符。如何强制编译器使用复制赋值?相关地,如何强制复制移动构造函数?基本上我要求反向 std::move()
我为什么想要这个?
第 1 行和第 3 行之间的代码(我无法更改)获取一些指向 的字段的指针,即重要的是,不改变 的a内存布局(移动最有可能做的事情),而是用新值覆盖。a
此外,我的对象只是std::vector. 当我移动分配它时,编译器只会将其底层数组的指针重定向到右值向量的数组。当我复制分配它时(并且之前的向量a更长),那么它的底层数组将被覆盖,但它们的地址将保持不变。不幸的是,“某些代码”存储了像 之类的指针&a[2],并且它们可能不会改变。
有没有办法在 cmake 中为创建的所有目标创建定义。到目前为止当我
add_compile_definitions(MYDEFINITION)
Run Code Online (Sandbox Code Playgroud)
在我的根 CmakeLists.txt 中,它似乎只为该文件中创建的目标创建这些定义。但我想为子目录中创建的所有目标创建定义。做这个的最好方式是什么?
我正在尝试使用模块在 C++ 20 中重建我的项目,以减少依赖性和编译时间。我尝试导入一些模块,并且可以这样做,但 Visual Studio 将导入语句标记为 undefined: "Could not find module file for..."。尽管它将其标记为错误,但我仍然能够编译并运行导入的函数(尽管如果它需要#include仅在模块中找到的单独函数而不是它导入到的 .cpp 文件,则它不允许我编译函数,给我一个链接器错误)。我密切关注微软的文档,并且能够在早期项目中使用模块,并且当时从未遇到过任何这些问题,并且我确保在该项目中重新建立相同的配置,但这种情况发生了。
我不太确定我还能提供哪些其他信息,但请询问是否有必要。任何帮助,将不胜感激
作品
import Object;
#include <iostream>
int main() {
calc(1, 5);
}
Run Code Online (Sandbox Code Playgroud)
export module Object;
export int calc(int a, int b) {
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
不起作用
import Object;
#include <iostream>
int main() {
calc(1, 5);
}
Run Code Online (Sandbox Code Playgroud)
export module Object;
#include <iostream>
export int calc(int a, int b) {
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,VS都会将其标记为错误
编辑
通过将#include …