小编son*_*yao的帖子

编译器错误C4430:缺少类型说明符 - 假定为int

我有这个错误:

"错误C4430:缺少类型说明符 - 假定为int.注意:C++不支持default-int"

使用此代码示例:

//A.h    
#include "B.h"
class A{
    B* b;
    ..
};

//B.h
#include "A.h"
class B{ 
    A* a; // error error C4430: missing type specifier - int assumed.
};
Run Code Online (Sandbox Code Playgroud)

c++ compiler-errors circular-dependency include

10
推荐指数
1
解决办法
7万
查看次数

C++外部类访问内部类的私有 - 为什么禁止

您好我想知道为什么C++标准允许我们在嵌套类中访问外部类的私有字段,而它禁止从外部类访问内部类的私有字段.我明白了,这个例子:

class OuterClass{
public:
    class InnerClass{
    public:
        void printOuterClass(OuterClass& outer) {cout << outer.m_dataToDisplay;};
    };
private:
    int m_dataToDisplay;
};
Run Code Online (Sandbox Code Playgroud)

很好,因为内心,有时可能会很复杂.但我认为以下情况也很好:

class Algorithm{
public:
    class AlgorithmResults{
    public:
        void readAlgorithmResult();
    private:
        void writeAlgorithmResult();
    };

    void calculate(AlgorithmResults& results, Arguments...){
       //calculate stuff
       results.writeAlgorithmResult(results);
    }
};
Run Code Online (Sandbox Code Playgroud)

对我来说,这种结构非常有意义,尽管在C++中是不允许的.我也注意到,有一段时间两者都被Java所允许,但现在第二个例子也被禁止了.是什么原因,第一个例子被允许而另一个被拒绝?

c++ private

10
推荐指数
3
解决办法
7662
查看次数

C++嵌套结构继承规则(访问受保护成员)

任何人都可以向我解释为什么(例如,"为什么语言是这样的?")以下代码在第二行有编译错误B::C::bar

class A
{
public:
    struct D
    {
        void call_foo (A &a)
        {
            a.foo ();
        }
    };

protected:
    void foo () {}
};

class B : public A
{
    struct C : public A::D
    {
        void bar (A &a, B &b)
        {
            b.foo (); // OK
            a.foo (); // Error. Huh?
            call_foo (a); // Ugly workaround
        }
    };
};
Run Code Online (Sandbox Code Playgroud)

当且仅当基指针的类型恰好是封闭类型(而不是某些父类型)时,似乎方法可以安全地在父类中使用受保护的方法.

这看起来很奇怪.为什么这种语言呢?

c++ inheritance protected language-lawyer

10
推荐指数
1
解决办法
1033
查看次数

如果constexpr没有丢弃在模板化的lambda中的假分支

我在模板化的lambda中遇到"if constexpr"的问题.为了论证,让我们忽略我是如何到达那里的,但我有一个结构foo,它以某种方式定义,产生如下内容:

template<bool condition>
struct foo {
    int a;

    // Only contains b if condition is true
    int b;
}
Run Code Online (Sandbox Code Playgroud)

现在我可以定义一个模板函数thtemplate

template<bool condition>
void print_fun(foo & obj) {
    /* Do something with obj.a */
    if constexpr(condition)
        /* Do something with obj.b */
};
Run Code Online (Sandbox Code Playgroud)

实例化这个功能,并使用它会编译,如果constexpr参数foo是一样的一个print_fun,即

constexpr bool no = false;
foo<no> obj = {};
print_fun<no>(obj);
Run Code Online (Sandbox Code Playgroud)

这会编译,因为假分支在模板化实体内被丢弃,因此在print_fun中使用obj.b没有问题.

但是,如果我定义一个类似的lambda表达式如下:

template<bool condition>
auto print_lambda = [](foo & obj) {
    /* Do something with obj.a */
    if constexpr(condition)
        /* Do something …
Run Code Online (Sandbox Code Playgroud)

c++ lambda templates c++17 if-constexpr

10
推荐指数
1
解决办法
796
查看次数

从已捕获的lambda中反复移动变量

我有以下测试代码:

#include <iostream>
#include <string>

void printValue(std::string&& val)
{
    std::cout << "Got value: " << val << "\n";
}

int main() {

    std::string testValue = "Test Value";

    auto lambda = [testValue = std::move(testValue)]() mutable
    {
        printValue(std::move(testValue));
    };

    lambda();
    lambda();
    lambda();
}
Run Code Online (Sandbox Code Playgroud)

我得到了结果:

Got value: Test Value
Got value: Test Value
Got value: Test Value
Run Code Online (Sandbox Code Playgroud)

它是一个有效的假设,从已经移动捕获的lambda中移动一个对象将始终具有它被移动到lambda中的初始状态,或者这只是一个对象处于"有效但未指定状态"的工件?

c++ lambda move-semantics c++11 c++14

10
推荐指数
1
解决办法
567
查看次数

为什么sfinae超载没有解决

这个版本工作正常:

template<typename T>
struct Foo
{
    template<typename U = T>
        typename std::enable_if<std::is_same<U,A>::value>::type
        bar() { std::cout << "1" << std::endl; }

    template<typename U = T> 
        typename std::enable_if<std::is_same<U,B>::value>::type
        bar() { std::cout << "2" << std::endl; }
};  
Run Code Online (Sandbox Code Playgroud)

此版本失败:

template<typename T>
struct Foo2
{
    template<typename U = T, typename V = typename std::enable_if<std::is_same<U,A>::value>::type >
        V bar() { std::cout << "1" << std::endl; }

    template<typename U = T, typename V = typename std::enable_if<std::is_same<U,B>::value>::type >
        V bar() { std::cout << "2" << std::endl; }
}; …
Run Code Online (Sandbox Code Playgroud)

c++ templates overloading sfinae

10
推荐指数
1
解决办法
136
查看次数

派生类无法访问基类的受保护成员

请考虑以下示例

class base
{
protected :
    int x = 5;
    int(base::*g);
};
class derived :public base
{
    void declare_value();
    derived();
};
void derived:: declare_value()
{
    g = &base::x;
}
derived::derived()
    :base()
{}
Run Code Online (Sandbox Code Playgroud)

根据知识,只有基类的朋友和派生类可以访问基类的受保护成员,但在上面的示例中,我得到以下错误,"Error C2248 'base::x': cannot access protected member declared in class "但是当我添加以下行时

friend class derived;
Run Code Online (Sandbox Code Playgroud)

声明它是朋友,我可以访问基类的成员,我在声明派生类时做了一些基本的错误吗?

c++ inheritance class protected

10
推荐指数
1
解决办法
1817
查看次数

用括号初始化的make_unique

https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique写入std::make_unique可以实现为

template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
Run Code Online (Sandbox Code Playgroud)

这对于没有构造函数的普通结构不起作用。可以将它们初始化,但没有非默认构造函数。例:

#include <memory>
struct point { int x, z; };
int main() { std::make_unique<point>(1, 2); }
Run Code Online (Sandbox Code Playgroud)

编译它会使编译器抱怨缺少2参数的构造函数,这是正确的。

我想知道,是否有任何技术理由不根据大括号初始化来定义函数?如

template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
    return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
}
Run Code Online (Sandbox Code Playgroud)

对于上面的方案,这已经足够好了。还有其他合法的用例会破坏吗?

看到总体趋势似乎倾向于使用括号进行初始化,我认为在该模板中制作括号是一种典型的选择,但是标准不这样做的事实可能表明我缺少某些东西。

c++ initialization unique-ptr c++-standard-library c++14

10
推荐指数
3
解决办法
687
查看次数

C++ 模板模板参数类型推导

我有代码可以在遍历字符串容器时找到并打印出模式的匹配项。打印在模板化的函数foo中执行

编码

#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <string>
#include <tuple>
#include <utility>

template<typename Iterator, template<typename> class Container>
void foo(Iterator first, Container<std::pair<Iterator, Iterator>> const &findings)
{
    for (auto const &finding : findings)
    {
        std::cout << "pos = " << std::distance(first, finding.first) << " ";
        std::copy(finding.first, finding.second, std::ostream_iterator<char>(std::cout));
        std::cout << '\n';
    }
}

int main()
{
    std::vector<std::string> strs = { "hello, world", "world my world", "world, it is me" };
    std::string const pattern = "world";
    for …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-templates language-lawyer c++11

10
推荐指数
1
解决办法
584
查看次数

为什么即使删除了复制构造函数,std::atomic 也能从 C++17 编译?

我有一个简单的代码:

#include <atomic>

int main()
{
    std::atomic<int> a = 0;
}
Run Code Online (Sandbox Code Playgroud)

这段代码可以在 GCC 11.1.0 和 -std=c++17 下正常编译,但在 -std=c++14 和 -std=c++11 时失败。

使用删除的函数 std::atomic::atomic(const std::atomic&)

这是为什么?在 C++17 类中std::atomic仍然没有复制构造函数。为什么此代码对 -std=c++17 有效?

当然,我知道首选样式是 use {},但我很好奇为什么上面的代码从 C++17 开始就可以很好地编译。

c++ initialization copy-elision stdatomic c++17

10
推荐指数
1
解决办法
251
查看次数