考虑这个例子(来自这里):
#include <type_traits>
#include <iostream>
template <typename U>
struct A {
};
struct B {
template <typename F = int>
A<F> f() { return A<F>{}; }
using default_return_type = decltype(std::declval<B>().f());
};
int main()
{
B::default_return_type x{};
std::cout << std::is_same< B::default_return_type, A<int>>::value;
}
Run Code Online (Sandbox Code Playgroud)
它在 gcc9.2 上编译没有错误,但 gcc7.2 和 clang 10.0.0 抱怨B
不完整。Clangs 错误是:
prog.cc:11:58: error: member access into incomplete type 'B'
using default_return_type = decltype(std::declval<B>().f());
^
prog.cc:7:8: note: definition of 'B' is not complete until the …
Run Code Online (Sandbox Code Playgroud) 我正在尝试lambdas以及不同的lambda表达式具有不同类型的事实,即使它们是相同的.考虑这段代码
#include <iostream>
template <typename T> void once(T t){
static bool first_call = true;
if (first_call) t();
first_call = false;
}
int main() {
int counter = 0;
auto a = [&counter](){counter++;};
once(a);
once(a);
std::cout << counter; // 1
auto b = a; // same type
once(b);
std::cout << counter; // 1
auto c = [&counter](){counter++;}; // different type
once(c);
once(c);
std::cout << counter; // 2
}
Run Code Online (Sandbox Code Playgroud)
此打印112
,即,a
和b
是相同类型的,当然和c
具有不同的类型.
是否允许编译器使用c
的类型与a …
std::array
是...(引用自cppreference):
该容器是一个聚合类型,其语义与将 C 样式数组
T[N]
作为其唯一非静态数据成员的结构体具有相同的语义。
这是否意味着数组的地址始终与其第一个元素的地址相同,即data()
?
#include <array>
#include <iostream>
int main()
{
std::array<int,6> x{};
std::cout << &x << "\n";
std::cout << x.data();
}
Run Code Online (Sandbox Code Playgroud)
可能的输出:
0x7ffc86a62860
0x7ffc86a62860
Run Code Online (Sandbox Code Playgroud)
如果是的话,这有什么用吗?允许以下行为吗?
int* p = reinterpret_cast<int*>(&x);
for (int i=0;i<6;++i){ std::cout << p[i]; }
Run Code Online (Sandbox Code Playgroud) 有人能解释我这里发生了什么......?
我有这个代码:
#include <fstream>
#include <string>
#include <iostream>
int main(){
std::ifstream file("test.txt");
std::string x;
while (true) {
if (!(file >> x)) return 0;
std::cout << x << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
...编译好,做它应该做的,到目前为止没问题.有时候,我不喜欢!
这么多,因为它可以很容易被忽略,所以我取代了if
用
if ((file >> x)==false) return 0;
Run Code Online (Sandbox Code Playgroud)
..突然我的编译器(gcc 4.8.5)抱怨警告:
warning: converting ‘false’ to pointer type ‘void*’ [-Wconversion-null]
if ((file >> x)==false) return 0;
Run Code Online (Sandbox Code Playgroud)
这就是我开始感到困惑的地方.哪里void*
来的?不>>
返回应该转换为的引用bool
吗?为什么false
转换成void*
?为什么在我不明确写的时候会触发相同的警告false
?
出于好奇,我也尝试了这个:
if ((file>>x)==true) return 0;
Run Code Online (Sandbox Code Playgroud)
从而引发一场错误风暴
error: no match for …
Run Code Online (Sandbox Code Playgroud) TL;DR:我正在寻找与以下 C++20 MWE 等效的 C++14:
template<int sz>
struct bits {
int v; // note explicit(expr) below
explicit(sz > 1) operator bool() const { return bool(v); }
};
int main() {
bool c = bits<1>{1}; // Should work
bool d = bits<3>{1}; // Should fail
}
Run Code Online (Sandbox Code Playgroud)
语境:
bits<sz>
我们有一个表示长度为位向量的C++ 类sz
。过去,对 all 的转换bool
是隐式的sz
,但事实证明这很容易出错,因此我们改为operator bool()
显式转换。
然而,1-bit
位向量(在我们的上下文中)几乎完全等同于布尔值,因此当 时最好是operator bool()
隐式的sz == 1
。
explicit(sz > 1)
这可以在C++20中实现,但我们的目标是 C++14。
我尝试重载 …
c++ implicit-conversion template-meta-programming c++14 c++20
头文件中“使用命名空间”被认为是不好的做法的原因之一(为什么“使用命名空间 std;”被认为是不好的做法?)是因为它将 using 指令“泄露”给包含头文件的每个人。C++ 模块仍然是这种情况吗?或者我可以“安全地”将 例如using namespace std
或using std::cout
放入我的模块中吗?:
module;
#include <iostream>
export module Module;
using namespace std;
// using std::cout;
export void greet() {
cout << "Hello World!\n";
}
Run Code Online (Sandbox Code Playgroud) 这是对成员声明中的模板类类型别名失败替换的跟进
考虑这个代码:
// A
template <typename T>
struct foo {
using type = unsigned;
template <type x>
void bar(type (&)[x]);
};
template <typename T>
template <typename foo<T>::type x>
void foo<T>::bar(type (&)[x]){}
Run Code Online (Sandbox Code Playgroud)
<source>:13:6: error: no declaration matches 'void foo<T>::bar(foo<T>::type (&)[x])'
13 | void foo<T>::bar(type (&)[x]){}
| ^~~~~~
<source>:8:10: note: candidate is: 'template<class T> template<unsigned int x> void foo<T>::bar(foo<T>::type (&)[x])'
8 | void bar(type (&)[x]);
| ^~~
<source>:4:8: note: 'struct foo<T>' defined here
4 | struct …
Run Code Online (Sandbox Code Playgroud) 我从来没有使用任何类型的智能指针,但当主题是指针时,我几乎无处不在地阅读它们.我知道有些情况下智能指针比原始指针更好用,因为在某种程度上它们可以管理指针的所有权.但是,我仍然不知道,"我不需要智能指针"和"这是智能指针的情况"之间的界限.
可以说,我有以下情况:
class A {
public:
double get1(){return 1;}
double get2(){return 2;}
};
class SomeUtilityClass {
public:
SomeUtilityClass(A* a) : a(a) {}
double getResult(){return a->get1() + a->get2();}
void setA(A* a){a = a;}
private:
A* a;
};
int main(int argc, char** argv) {
A a;
SomeUtilityClass u(&a);
std::cout << u.getResult() << std::endl;
A a2;
u.setA(&a2);
std::cout << u.getResult() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这当然是一个过于简单的例子.我的意思是SomeUtilityClass
不应该"拥有"一个实例A
(因为它只是一个实用类),因此它只是一个指针.
关于指针,我所知道的唯一可能出错的是:
SomeUtilityClass
可以使用空指针进行实例化SomeUtilityClass
注意到它智能指针如何帮助避免这个问题?在这种情况下,使用智能指针可以获得哪些其他好处?
PS:我知道智能指针有几个问题(例如这个).但是,如果您能告诉我有关此特定示例的影响,我将不胜感激.
我正在编写一些代码,在那里我遇到了类似于这个的情况:
struct Bar;
struct Foo{
friend struct Bar;
private:
Foo(){}
void f(){}
void g(){}
};
struct Bar {
Foo* f;
Bar() { f = new Foo();}
~Bar() { delete f;}
};
int main(){
Bar b;
}
Run Code Online (Sandbox Code Playgroud)
我宁愿Bar
不作为friend
的Foo
,因为除了Foo
构造函数Bar
不需要访问任何的Foo
私有方法(因此不应该有访问).有没有办法只允许Bar
创建Foo
s而不让他们成为朋友?
PS:意识到问题可能不是100%清楚.我不介意它是否是通过朋友,只是所有人Bar
都可以访问所有私人方法的事实令我感到不安(这通常是这种情况friends
),这就是我想要避免的.幸运的是,到目前为止,没有一个答案与这个糟糕的表述有问题.
我正在阅读有关严格别名的内容,但它仍然有点模糊,我无法确定定义/未定义行为的界限.我发现最详细的帖子集中在C.所以如果你能告诉我这是否允许以及自C++ 98/11以来发生了什么变化,那将是很好的...
#include <iostream>
#include <cstring>
template <typename T> T transform(T t);
struct my_buffer {
char data[128];
unsigned pos;
my_buffer() : pos(0) {}
void rewind() { pos = 0; }
template <typename T> void push_via_pointer_cast(const T& t) {
*reinterpret_cast<T*>(&data[pos]) = transform(t);
pos += sizeof(T);
}
template <typename T> void pop_via_pointer_cast(T& t) {
t = transform( *reinterpret_cast<T*>(&data[pos]) );
pos += sizeof(T);
}
};
// actually do some real transformation here (and actually also needs an inverse)
// ie this …
Run Code Online (Sandbox Code Playgroud)