小编gex*_*ide的帖子

部分模板专业化仅限于某些类型

是否可以编写仅用于类类型的部分模板特化,例如,从特定类继承或遵守可通过类型特征表达的其他约束?即,像这样:

class A{}

class B : public A{}

template<typename T>
class X{
    int foo(){ return 4; }
};

//Insert some magic that allows this partial specialization
//only for classes which are a subtype of A
template<typename T> 
class X<T>{
    int foo(){ return 5; }
};

int main(){
    X<int> x;
    x.foo(); //Returns 4
    X<A> y;
    y.foo(); //Returns 5
    X<B> z;
    z.foo(); //Returns 5
    X<A*> x2; 
    x2.foo(); //Returns 4
}
Run Code Online (Sandbox Code Playgroud)

c++ templates type-traits template-specialization

5
推荐指数
1
解决办法
1017
查看次数

C++:使用segvcatch安全吗?

我偶然发现了segvcatch库,它承诺将segfaults和浮点错误包装到适当的异常中.

使用这个库是安全的,如果我添加了捕获的所有段错误只会是空指针访问的前提条件(即,没有数组溢出或无效指针可能在segfaulting之前完全搞砸了内存,导致未定义的行为无论如何)?在捕获nullptr段错误后,程序是否仍然定义了语义?浮点错误呢?他们表现得更好/不同吗?

旁注:请不要评论说任何产生段错误的程序都是格式错误的,应该进行调试/修复.我知道,我同意.不过,我对这个问题很感兴趣.

c++ signals exception-handling segmentation-fault

5
推荐指数
1
解决办法
763
查看次数

C/C++如何复制结构?

在按值传递C/C++中的结构时,必须复制结构内容.编译器如何实现这一目标?即,通常为此副本发出哪些汇编指令?

这些时间有多快,例如与memcpy的调用相比?

现在考虑这段代码:

struct X { int i, j, k; };

void foo(X x);

void foo( int i, int j, int k);
Run Code Online (Sandbox Code Playgroud)

调用foo(X)和foo(int,int,int)之间有什么区别,或者生成的汇编代码是否相同(考虑参数的传递)?

c c++ struct copy

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

C++ STL:为什么没有找到比特定键小的最大元素的upper_bound等效项?

通常,STL是为了速度而构建的.但是,在map和set数据结构上只有upper_bound和lower_bound,并且没有操作来检索具有小于输入键的最大键的条目k.为什么是这样?我知道我可以简单地做一个lower_bound并做一个--it来检索这个,但是根据数据结构,可以更有效地立即搜索正确的条目,而不是搜索另一个然后返回一步.

例如,std::map使用红黑树,即二叉搜索树.如果返回的upper_bound元素是大于根的最小元素,则--it必须返回到根,查询O(log n)附加成本.

如果这是Java,我会对设计决定没问题.但是,STL是为最大速度而构建的,那么为什么这个操作被遗漏了呢?

澄清:我不是在谈论std::upper_bound它可以采取另一种比较,但方法std::mapstd::set.

c++ stl binary-search-tree

4
推荐指数
1
解决办法
615
查看次数

模板专业化不起作用

请考虑以下代码:

template<typename T, size_t... i>
class Bar{};

template<typename T1, typename T2>
class Foo{};

template<typename T1, size_t... i1>
template<typename T2, size_t... i2>
struct Foo<Bar<T1,i1...>,Bar<T2,i2...>>
{
    struct Eq {};
};
Run Code Online (Sandbox Code Playgroud)

如您所见,有一种可变参数类型Bar<T,size_t...>和类型Foo<T1,T2>.如果将两个Bars用作模板参数,则Foo具有特殊性.这种专业化具有内在类型Eq.

但是,以下不起作用:

typename Foo<Bar<int,2>,Bar<int,3>>::Eq b;
Run Code Online (Sandbox Code Playgroud)

它讲述的是没有类型EqFoo<Bar<int,2>,Bar<int,3>>,即,编译器不挑模板专业化,但基本定义的Foo<T1,T2>这的确没有内在的Eq类型.

我在这做错了什么?为什么编译器不选择专门化?

c++ templates template-specialization variadic-templates c++11

4
推荐指数
1
解决办法
196
查看次数

模板结构中的Friend运算符会引发重定义错误

考虑以下代码:

template<typename T,typename K>
struct A{

   friend std::ostream& operator<<(std::ostream& out, K x) { 
      // Do some output 
      return out; 
   }

};

int main(){
   A<int,int> i;
   A<double,int> j;
}
Run Code Online (Sandbox Code Playgroud)

它没有编译,因为A的两个实例化operator<<使用相同的签名实例化了两次,所以我收到了这个错误:

test.cpp:26:25: error: redefinition of ‘std::ostream& operator<<(std::ostream&, int)’
    friend std::ostream& operator<<(std::ostream& out, K x) { return out; }
                         ^
test.cpp:26:25: error: ‘std::ostream& operator<<(std::ostream&, int)’ previously defined here
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题?如果该运算符可能具有两个不同实例的相同签名,那么如何在模板中拥有友元运算符?如何在不触发重新定义错误的情况下解决此问题?

c++ templates operator-overloading c++11

4
推荐指数
2
解决办法
765
查看次数

测试是否在宏内定义了预处理器符号

测试是否定义了预处理器符号的常用方法是使用#ifdef。但是,#ifdef不能在宏中使用。我需要的是一种检查宏的参数,如果该宏的参数是已定义的预处理程序符号。

例如:

#define TRACE(x,y) if(IS_DEFINED(x)){ std::cout << y; }
Run Code Online (Sandbox Code Playgroud)

在这里,TRACE有两个参数,第一个x应该是预处理器符号的名称。如果定义了此类符号,则应打印第二个参数。IS_DEFINED我正在寻找不存在的功能/宏。

用法如下:

#undef BLA
TRACE(BLA,"abc") // "abc" won't be printed, as BLA is not defined
#define BLA 1
TRACE(BLA,"xyz") // "xyz" will be printed, as BLA is a defined symbol
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?也许一些宏魔术?当然,该解决方案应该适用于任何符号,不仅适用于符号,也适用于BLA一组硬编码符号。如果要事先知道要检查的符号集,显然很容易。

c macros c-preprocessor

4
推荐指数
4
解决办法
2253
查看次数

功能在先决条件

A有一个制作目标foo/%.bar.它匹配以下文件:

foo/x/y/z.bar foo/a.bar

现在,我想要一个prereq.o必须与文件位于同一文件夹中的先决条件.bar.因此,对于foo/x/y/z.bar先决条件应该是foo/x/y/prereq.o,foo/a.bar应该是foo/prereq.o.

怎么做到这一点?

我尝试使用这样的dir功能:

foo/%.bar : foo/$(dir %)prereq.o

但是,这不起作用,因为在扩展模式之前评估函数.那么它是怎样工作的?

makefile gnu-make

4
推荐指数
1
解决办法
504
查看次数

模板成员默认初始化

假设我有以下模板

template <typename T>
class{
   T t;
};
Run Code Online (Sandbox Code Playgroud)

现在,我想添加一个构造函数,用它的类型的默认值初始化t.也就是说,对于数值类型,t应初始化为0,对于指针,t应初始化为nullptr.最后,可能还有其他类型的结构.这里,一个好的初始化将是默认的构造函数(无论如何都会被调用,所以我不必在这里做任何事情).

在结论中,我正在寻找这样的事情:

template<typename T>
class X{
    T t;
    X() : t(default_value<T>::value);
}
Run Code Online (Sandbox Code Playgroud)

正如我想象中的语法指出的那样,我认为使用某种具有不同特殊性的模板可能会带有默认值.但是如何处理结构和类?由于我已经指定t(...),默认构造函数不再是一个选项.

c++ templates initialization default-value

3
推荐指数
1
解决办法
5859
查看次数

为什么 C++ 编译器在将 POD 移动到带有 RVO 的可选选项时不能省略移动?

考虑以下代码(godbolt):

#include <optional>
#include <array>

struct LargeType {
    std::array<int, 256> largeContents;
};

LargeType doSomething();

std::optional<LargeType> wrapIntoOptional(){
    return std::optional<LargeType> {doSomething()};
}
Run Code Online (Sandbox Code Playgroud)

如您所见,有一个函数返回一个大 POD,然后有一个函数将其包装到std::optional. 正如在 godbolt 中可见,编译器memcpy在此处创建了一个,因此它不能完全避免移动对象。为什么是这样?

如果我理解正确的话,C++ 语言将允许由于假设规则而省略移动,因为它没有明显的副作用。看来编译器确实无法避免。但为什么?

我(可能不正确)的理解是编译器如何优化输出,memcpy将对可选内部存储的引用传递给doSomething()(因为我猜这么大的对象无论如何都会通过隐藏引用传递)。wrapIntoOptional由于 RVO,可选本身已经位于调用者的堆栈上。由于 的构造函数的定义std::optional位于标头中,因此编译器可以使用它,因此它应该能够内联它,因此它可以doSomething首先将该存储位置传递给它。那么我的直觉出了什么问题呢?

澄清一下:我并不认为 C++ 语言要求编译器内联它。我只是认为这将是一个合理的优化,并且考虑到将事物包装到可选值中是一种常见的操作,这将是在现代编译器中实现的优化。

c++ optimization return-value-optimization as-if

3
推荐指数
1
解决办法
128
查看次数