我有以下代码:
class C {
public:
C(int) {}
C(const C&) {}
C() {}
};
class D : public C {
public:
using C::C;
};
int main() {
C c;
D d_from_c(c); // does not compile, copy ctor is not inherited
D d_from_int(1); // compiles, C(int) is inherited
}
Run Code Online (Sandbox Code Playgroud)
衍生类应该继承除默认ctor之外的所有基数(这里解释).但为什么复制ctor也不是继承的呢?相关问题的论据在这里是不可接受的.
代码使用g ++ 4.8.1编译.
阅读了最令人烦恼的解析后,我进行了一些实验并找到了这个程序.有两条非常相似的线.其中一个在g ++ 7和clang ++ - 3.9中产生警告,另一个则没有.
int main() {
void(); // no warning
int(); // warning: statement has no effect
}
Run Code Online (Sandbox Code Playgroud)
在第二行中,创建了一个默认构造的类型对象int
并立即销毁,因此未使用.但是第一行会发生什么?如果以相同的方式解析它,则应该是错误,因为创建类型的对象是非法的void
.另一方面,它看起来也不像函数声明.
I've just installed PyCharm Community Edition 3.4.1 and tried to make a simple pygame project in it. I found that code completion runs in a weird way. In this case:
from pygame import event
event.
Run Code Online (Sandbox Code Playgroud)
when I type event.
a completion popup with event
methods shows immediately. But in the second case:
import pygame
pygame.event.
Run Code Online (Sandbox Code Playgroud)
a popup contains only object
methods.
How can I learn the autocomplete tool to look deeper into the library?
我有一个C
有任何铸造操作员的课程.在示例中,我尝试以std::string
三种不同的方式转换它的实例:static_cast
,构造函数std::string
和赋值std::string
.但是,只有最后一个编译,而其他人引发了模糊构造函数的错误.
错误的原因很明显:有很多方法可以转换C
为构造函数std::string
可以接受的东西.但这些案件有什么区别?为什么演员在这里按预期工作但不在那里?
struct C {
template<typename T>
operator T() const {
return T{};
}
};
int main() {
C c;
cout << static_cast<string>(c) << endl; // compile error
string bad(c); // compile error
string ok = c; // compiles successfully
}
Run Code Online (Sandbox Code Playgroud)
UPD:正如bolov在评论中提到的,这个问题不能用C++ 17重现.我用g ++ - 5和clang-3.8用-std = c ++ 11和-std = c ++ 14测试它,它显示了所描述的错误.
我if constexpr
检查了一个类型是否与自身相等。我用std::is_invocable_v<std::equal_to<>, T, T>
.
但是,当T
是一个由不可比结构组成的向量时,该代码段错误地返回 True。有什么深层原因还是编译器错误?
最小的例子如下。
#include <type_traits>
#include <iostream>
#include <vector>
class TNonComparable{};
int main()
{
std::cout << std::is_invocable_v<std::equal_to<>, TNonComparable, TNonComparable> << "\n";
// 0
std::cout << std::is_invocable_v<
std::equal_to<>,
std::vector<TNonComparable>,
std::vector<TNonComparable>
> << "\n";
// 1
std::vector<TNonComparable> vec;
// vec == vec;
// (expected) compilation error
}
Run Code Online (Sandbox Code Playgroud)
我检查了 Godbolt 的输出,所有最新版本的 g++ 和 clang 都是一样的。
我想创建一个自定义迭代器包装器,例如enumerate
:给定一对 type 上的迭代器T
,它将返回一个可迭代的 typestd::pair<const int, T&>
,其中该对的第一个元素将采用值 0、1、2,依此类推。
我无法弄清楚应该是什么value_type
以及reference
我在弄清楚我的迭代器我想支持两种行为:
首先,引用底层序列的值:
for (auto& kv: enumerate(my_vec)) {
kv.second = kv.first;
}
Run Code Online (Sandbox Code Playgroud)
(有点std::iota
);
其次,复制该值:
std::vector<int> a{10, 20, 30};
auto copy = *enumerate(a).begin();
a[0] = 15;
std::cout << copy.first << " " << copy.second; // 0 10
Run Code Online (Sandbox Code Playgroud)
我很困惑 的返回类型应该是什么Iterator::operator*()
。如果是,std::pair<const int, T&>
则第二个示例中的值将不会被复制。如果是,std::pair<const int, T>
那么在第一个示例中就不可能引用基础值。我应该做什么,应该做什么value_type
,reference
以及pointer
这样的迭代器的 typedef?
这是我实现它的尝试。它支持引用但不支持复制。
template<typename T>
struct Iterator {
using …
Run Code Online (Sandbox Code Playgroud) 例如,存在类的层次结构Base -> A -> B
。
每当A::A()
被调用时,实际要构造的对象可能是 class A
,然后它是最后一个被调用的 ctor ;或 class B
,然后B::B()
稍后会调用。是否可以区分这些情况并检测当前正在调用的构造函数是否属于实际正在构造的类型?
引人注目的解决方案是使用typeid
:
A::A() {
if (typeid(this) == typeid(A*)) {
// A is the actual type of the object being constructed
}
}
Run Code Online (Sandbox Code Playgroud)
但是,typeid
(以及 vtable)在构造函数和析构函数中的工作方式不同,并且不公开最终类,而是返回有关当前(静态)类本身的信息。这是因为层次结构中更深层的类的构造函数尚未被调用,因此从已构造的父类访问它们是非法的。请参阅cppreference解释部分的最后一段。
我不需要知道正在构造的对象的确切类型,而只需要检测当前构造函数是否是最终构造函数。有可能做到吗?
我可以修改类的主体Base
和所有其他类的构造函数。A
和的身体B
不受我的控制。
C++20 就可以了。
编辑:我将尝试详细说明哪些代码可以修改,哪些不能修改。
首先,我拥有对Base
. 它始终是层次结构的基类。
然后库的用户可以像这样定义后代类:
class A : public Base
{
REGISTER(A);
// some user code
};
class B …
Run Code Online (Sandbox Code Playgroud) 我需要在小数点后打印四舍五入到可变位数的双精度数,这样就不会打印出无效的零.例如,我希望数字123和123.4都按原样打印 - 第一个没有小数点,第二个没有小数点.如果小数点后有多位有效数字,则该数字应截断为六位数.
我描述的是boost :: locale :: format的默认行为,如果你打印数字boost::locale::format("{1,number}") % double_value
.我需要的是在Java中做同样的事情,最好使用String.format.我试过%f
和%g
,但他们两人打印至少六位数字.
我想要格式化的所有数字都在[0.1,30000]范围内,所以转向科学形式不应该是一种痛苦.
我的应用程序评估用户指定的一些整数表达式.我想检测所有潜在的错误并报告它们.
所有计算都在int64_t
(签名)完成.式可以包括几乎所有的C++二进制运算符(+
,-
,*
,/
,%
,|
,||
,&
,&&
,和六比较运算符)和整数(可能是负数).
问题是:在评估可能使我的程序终止的表达式时可能发生什么错误?我想出了其中两个:
std::numeric_limits<int64_t>::min()
-1.也可能出现有符号整数溢出,但是,据我所知,在这样的设置中它不能对大多数CPU做任何有害的事情,所以我们忽略它.
比方说,我有一节课vector<T>
.我想实现两个getter方法,分别返回T&
和const T&
.我不想实现它们.相反,我想只实现const版本,然后在非const方法中重用它的代码const_cast
.
template<typename T>
class Vector {
public:
T& operator[](size_t i) {
return const_cast<T&>(
static_cast<const Vector<T>*>(this)->operator[](i));
}
const T& operator[](size_t i) const {
return data[i];
}
private:
T* data;
};
Run Code Online (Sandbox Code Playgroud)
这种方法可能存在哪些陷阱?或者,是否有任何方法可以检查const_cast在任何确切的情况下是否合法?
最后,处理这种重复的const /非const代码的常用方法是什么?
我是编程语言的新手,有没有办法在运行时将不同的数据类型存储在一个变量中.EX:
class a
{
void b(anydatatype var)
int ab;
}
void a::b(anydatatype var)
{
ab = var;
//how can i make this possible to assign any data type to that int?
}
Run Code Online (Sandbox Code Playgroud)
如果我在不使用模板的情况下获得解决方案,那将会非常有用
我有多个相同功能的重载.对于某些参数集,几个重载相同,我自然会得到一个"模糊过载"错误.我想在某种程度上定义这些函数的优先级,以便在模糊的情况下选择具有最小优先级的那个.
我试图让一系列的模板辅助类,"标签", P<0>
,P<1>
,...,从而P<N>
继承了P<N+1>
一些上限.因此,如果有两个函数f(P<2>)
和f(P<4>)
,和我打电话f(P<0>)
,第一个被选择.
它在实践中不起作用.具有经典"int/long"和"long/int"函数的"干净"示例仍然会产生歧义.我试图在函数中添加几个标记参数来增加标记的"权重",但它确实没有帮助.
这种方法能以某种方式调整吗?
constexpr static int MAX = 20;
template<int N, class Enable = void>
class P {};
template<int N>
class P<N, typename std::enable_if<N < MAX, void>::type> : public P<N+1> {};
void f(int, long, P<2>) {}
void f(long, int, P<5>) {}
int main() {
f(1, 2, P<0>());
}
Run Code Online (Sandbox Code Playgroud) c++ ×10
templates ×3
inheritance ×2
c ×1
c++11 ×1
c++20 ×1
casting ×1
constructor ×1
formatting ×1
iterator ×1
java ×1
overloading ×1
precision ×1
pycharm ×1
pygame ×1
python ×1
type-traits ×1