小编Gui*_*cot的帖子

与CRTP clonable类无关的协变类型

我正在尝试使用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++ multiple-inheritance crtp cloneable covariant

6
推荐指数
2
解决办法
500
查看次数

Visual Studio 2015无法编译有效代码(std函数错误?)

我最近在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)

c++ templates visual-c++ c++11 visual-studio-2015

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

未定义的引用,模板结构和constexpr静态成员

我的模板结构的静态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++ templates static-members constexpr c++14

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

在派生类中使用基础构造函数的任何方法?

在过去的十年或二十年中使用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)

但这似乎是很多打字,特别是如果我打算从基类派生许多类.

基类仍然需要这些或那些参数.有没有办法不必为每个派生类重写这个参数,或者"暴露"基础构造函数,或者我必须像以前一样完全按照这样做?

c++ inheritance constructor

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

我应该担心C++ 17中的Wmissing-field-initializers和聚合初始化吗?

我用GCC编译了一些代码-Wall-Wextra启用了.此代码生成警告:

struct A { A(int) {} };
struct B {};

struct C : A, B {};

int main() {
    (void) C{1};
}
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};
               ^
Run Code Online (Sandbox Code Playgroud)

我应该担心吗?这是GCC输出此警告的错误吗?似乎我没有要初始化的字段,也没有缺少参数.

c++ aggregate-initialization c++17

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

Does std::integral_constant&lt;T, v&gt;::value always have a definition?

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++ c++14

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

vector_base继承与组合

简短问题:

是否有为什么C ++ STL实现使用一个原因vector_base结构/类(到手柄资源和分配器),为基类std::vector,而不是使用组合物

较长版本:

在提高我对C ++的了解的“任务”中,我一直在尝试重新实现一个Vector大多数是std::合规的类。我想我已经足够了解为什么使用分配器明智,为什么您实际上希望将所有内存处理放在单独的类/结构(RAII等)中,但我看不到为什么我们std::vector要从中继承类,而不是将其作为私人成员。 例如,LLVMgcc都使用继承。另一方面,我发现构造函数和赋值运算符(尤其是move-types)使用合成更容易处理。

我只是公开我对语言的肤浅知识吗?

举例来说,我搜索了一本教科书,发现Stroustroup的书与他的2013年的“ C ++编程语言,第四版”对标准的“模拟重新实现”有不同的版本(只是让我更加困惑!)。使用构图及其2014年的“编程:原理与实践,第二版”。使用继承!

任何人都可以帮助我阐明一些想法吗?

c++ stl

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

强制复制分配优于移动分配运算符

假设我有一个定义了复制和移动赋值运算符的对象。当我写下这个:

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],并且它们可能不会改变。

c++ move copy-constructor move-constructor

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

Cmake add_compile_definitions 但适用于所有目标

有没有办法在 cmake 中为创建的所有目标创建定义。到目前为止当我

add_compile_definitions(MYDEFINITION)
Run Code Online (Sandbox Code Playgroud)

在我的根 CmakeLists.txt 中,它似乎只为该文件中创建的目标创建这些定义。但我想为子目录中创建的所有目标创建定义。做这个的最好方式是什么?

c c++ cmake

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

无法导入 C++ 模块

我正在尝试使用模块在 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 …

c++ import module c++20

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