我使用g ++来编译带有压缩字段的代码.但是,我尝试返回对打包字段的引用时收到错误.
例:
struct __attribute__((packed)) Foo {
int* ptr;
uint16_t foo;
int*& getPtr(){
return ptr;
}
};
Run Code Online (Sandbox Code Playgroud)
产量错误:
test.cpp:22:14: error: cannot bind packed field ‘((Foo*)this)->Foo::ptr’ to ‘int*&’
return ptr;
Run Code Online (Sandbox Code Playgroud)
为什么我不能返回对打包字段的引用?
通常,将结构S视为接口I会触发结构的自动装箱,如果经常这样做会对性能产生影响.但是,如果我编写一个带有类型参数的泛型方法并用a T : I调用它S,那么编译器是否会省略装箱,因为它知道类型S并且不必使用接口?
这段代码显示了我的观点:
interface I{
void foo();
}
struct S : I {
public void foo() { /* do something */ }
}
class Y {
void doFoo(I i){
i.foo();
}
void doFooGeneric<T>(T t) where T : I {
t.foo(); // <--- Will an S be boxed here??
}
public static void Main(string[] args){
S x;
doFoo(x); // x is boxed
doFooGeneric(x); // x is not boxed, at least …Run Code Online (Sandbox Code Playgroud) 我需要[[nodiscard]]非C++ 17代码库中属性的语义.我想在C++ 17之前有编译器相关的方法来实现这一点.有谁知道这些?我对clang,gcc和MSVC感兴趣.
C++20 给了我们飞船操作符,甚至允许我们使用default它,用默认语义生成所有比较,这将从我们的代码库中删除很多样板,太棒了!
但是平等和不平等呢?C++20 是否也给了我们一条通往default平等和不平等的道路?根据cppreference.com,默认的飞船只会给我们那么,有没有办法在 C++20 中也(或仅)默认生成< <= >, and >=,而不是==and !=。鉴于我通常需要更多/更少的平等/不平等方式,这似乎很不幸。==和!=?
更新:该页面现在包含对 defaulting 的描述operator==。似乎我在添加文档前两小时访问了该页面。:D
这个问题正在考虑模板类的明确实例化.
考虑B<T>从另一个模板类派生的模板类A<T>.我想明确地实例化,B<T>因为它的方法是从动态链接调用的,所以这些方法必须实例化,尽管它们不是在代码本身中调用的.当然,也会调用从中继承的方法A<T>,因此它们也必须实例化.
似乎C++在显式实例化模板类时不会实例化基类,如本问题所述: C++类模板的显式实例化是否实例化依赖基类? 例:
template<typename T>
class A{ void foo(){...} };
template<typename T>
class B : public A<T> {}
template class B<int>; // This will NOT instanciate A<int>::foo()!!!
Run Code Online (Sandbox Code Playgroud)
当然,我还需要实现所有基类.但是,我不想用此负担客户端代码,因为类层次结构可能非常深.考虑涉及10个或更多模板类的类层次结构.不应该敦促客户编写10个显式模板实例.这不仅仅是大量的写作; 当我向类层次结构引入更改时,它也会中断.
相反,我想以某种方式实现无论何时实现B<T>,那么它的所有基类都是如此.我尝试简单地在B本身中实现基类,如下所示:
template<typename T>
class B : public A<T> {
template class A<T>; // Does not compile!
}
Run Code Online (Sandbox Code Playgroud)
但这不编译.还有其他方法可以实现这一目标吗?
C++允许通过创建一个operator T()where T我们想要转换为的类型来重载类型转换.
现在,此功能如何与引用一起使用?例如:
struct Y{ int i; };
struct X{
Y y;
operator Y() const { return y; }
};
Run Code Online (Sandbox Code Playgroud)
在这里,我们可以强制X转换Y包含的内容Y.但是,如果我们想要对某个Y参考进行强制转换呢?例如,C++允许我们这样做:
struct X{
Y y;
operator Y&(){ return y; }
operator const Y&() const { return y; }
};
Run Code Online (Sandbox Code Playgroud)
现在,我们可以X转换为Y引用或const引用(也适用于a const X).
第一个和第二个例子的语义有什么不同吗?如果我想允许转换为引用,最好的方法是什么?
我可以想象,即使我operator T()没有任何写入&,C++可能允许转换通过引用返回结果(即,operator T&()当我指定时它可能以某种方式添加隐式方法operator T()).
例如,我想要以下代码工作:
int main(){
X x;
Y& …Run Code Online (Sandbox Code Playgroud) 有可能以某种方式使部分模板规范成为朋友类吗?即你认为你有以下模板类
template <class T> class X{
T t;
};
Run Code Online (Sandbox Code Playgroud)
现在你有部分特化,例如,指针
template <class T> class X<T*>{
T* t;
};
Run Code Online (Sandbox Code Playgroud)
我想做到的是,每一个可能X<T*>是朋友类X<S>为ANY S.即X<A*>应该是的朋友X<B>.
当然,我想到了X中通常的模板朋友声明:
template <class T> class X{
template <class S> friend class X<S*>;
}
Run Code Online (Sandbox Code Playgroud)
但是,这不能编译,g ++告诉我这个:
test4.cpp:34:15:错误:' template<class T> class X'的特化必须出现在命名空间范围内
test4.cpp:34:21:错误:部分特化' X<S*>'声明'朋友'
这根本不可能,还是有一些解决方法?
我之所以要问的是,我需要一个构造函数,X<T*>从任意X<S>(S必须是子类型T)创建这个类.
代码如下所示:
template <class T> class X<T*>{
T* t;
template<class S>
X(X<S> x) : t(&(x.t)) {} //Error, x.t …Run Code Online (Sandbox Code Playgroud) c++ templates partial-specialization template-specialization friend-class
在我之前的问题中,我想使用static_assert将模板参数限制为特定的子类型.问题得到了解答,获得批准的代码如下:
template <typename T>
struct X {
static_assert(std::is_base_of<Y,T>::value,"T must be derived from Y!");
};
Run Code Online (Sandbox Code Playgroud)
现在,我想让错误信息更简洁.即,我想说明哪种类型违反了这种约束.例如,如果类A不是从Y某个实例派生出来的X<A>,那么错误消息应该打印"类型参数必须从Y派生,但A不是".
这是用标准库实现的吗?
我看到两个挑战:
docx4j的"入门"文档包含将docx写入pdf的示例代码:
// Set up converter
org.docx4j.convert.out.pdf.PdfConversion c =
new org.docx4j.convert.out.pdf.viaXSLFO.Conversion(wordMLPackage);
Run Code Online (Sandbox Code Playgroud)
但是,从docx4j 3.0开始,整个PdfConversion工具似乎已被弃用,但没有通知现在如何执行转换.那么使用docx4j 3.0将docx转换为pdf的非弃用方法是什么?
我最近问了这个问题:
问题是我正在写一个类型的数组,uint8_t并且编译器将它视为可以使用this方法的指针(类型struct T*)进行别名,因为void*和char*(= uint8_t*)总是可以在C++中对任何其他指针进行别名.此行为导致错过优化机会.当然,我想避免这种情况.所以问题是:我是否可以声明一个uint8_t强制执行严格别名的数组,即编译器将其视为从不与另一种类型的指针混淆?也就是说,我在寻找的东西像一个strict_uint8_t类型,它是一种uint8_t具有特殊混淆的行为.有没有办法实现这个目标?
显示我的意思的示例代码,借用其他问题并简化.有关更多详细信息,请阅读链接的问题及其接受的答案:
struct T{
uint8_t* target;
void unpack3bit(char* source, int size) {
while(size > 0){
uint64_t t = *reinterpret_cast<uint64_t*>(source);
/** `this->target` cannot be cached in a register here but has
to be reloaded 16 times because the compiler
thinks that `this->target` could alias with `this` itself.
What I want is a special uint8_t type that does not trigger
this …Run Code Online (Sandbox Code Playgroud) c++ ×8
c++11 ×3
templates ×3
reference ×2
assertions ×1
autoboxing ×1
c# ×1
c++20 ×1
casting ×1
docx4j ×1
friend-class ×1
gcc ×1
generics ×1
inheritance ×1
interface ×1
packed ×1
pdf ×1
pointers ×1