我有这个错误:
"错误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++标准允许我们在嵌套类中访问外部类的私有字段,而它禁止从外部类访问内部类的私有字段.我明白了,这个例子:
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所允许,但现在第二个例子也被禁止了.是什么原因,第一个例子被允许而另一个被拒绝?
任何人都可以向我解释为什么(例如,"为什么语言是这样的?")以下代码在第二行有编译错误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)
当且仅当基指针的类型恰好是封闭类型(而不是某些父类型)时,似乎方法可以安全地在父类中使用受保护的方法.
这看起来很奇怪.为什么这种语言呢?
我在模板化的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) 我有以下测试代码:
#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中的初始状态,或者这只是一个对象处于"有效但未指定状态"的工件?
这个版本工作正常:
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) 请考虑以下示例
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)
声明它是朋友,我可以访问基类的成员,我在声明派生类时做了一些基本的错误吗?
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)
对于上面的方案,这已经足够好了。还有其他合法的用例会破坏吗?
看到总体趋势似乎倾向于使用括号进行初始化,我认为在该模板中制作括号是一种典型的选择,但是标准不这样做的事实可能表明我缺少某些东西。
我有代码可以在遍历字符串容器时找到并打印出模式的匹配项。打印在模板化的函数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) 我有一个简单的代码:
#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++ ×10
templates ×3
c++11 ×2
c++14 ×2
c++17 ×2
inheritance ×2
lambda ×2
protected ×2
class ×1
copy-elision ×1
if-constexpr ×1
include ×1
overloading ×1
private ×1
sfinae ×1
stdatomic ×1
unique-ptr ×1