小编Joh*_*erg的帖子

std :: tuple和std :: pair是否支持聚合初始化?

聚合初始化除其他外不需要用户提供的构造函数.但是std::tuple,std::pair对有一大堆重载的构造函数.从核心语言的角度来看,这些构造函数是用户提供的还是用户声明的

使用C++ 17,可以编写(更新/澄清:nocopy是一个无法复制或移动的类,例如std::mutex)

auto get_ensured_rvo_str(){
   return std::pair(std::string(),nocopy());
}
Run Code Online (Sandbox Code Playgroud)

编辑:不,这是不可能的,如链接答案和下面的答案所解释.

这需要聚合初始化(对于上下文:具有不可移动类型的多个返回值(结构化绑定)和C++中保证的RVO 17).

tuplepair特殊标准语言的支持,让这(在构造函数中的存在)?:

20.5.2.1施工

... EXPLICIT constexpr元组(const类型&...);

6效果:构造函数使用相应参数的值初始化每个元素.

或者我们原则上可以自己编写tuple或者pair

c++ tuples aggregate std-pair c++17

8
推荐指数
1
解决办法
698
查看次数

编译时间类型转换检查(constexpr和用户定义的文字)

更新:我下面贴我自己的答案 在这里,还有这件事情更长的版本:http://scrupulousabstractions.tumblr.com/post/38460349771/c-11-type-safe-use-of-integer-user-defined-文字

题:

我做了一个简单的constexpr用户定义的文字_X是可以获得价值为unsigned long long(这是字面定义用户如何工作的数字:http://en.cppreference.com/w/cpp/language/user_literal),然后我做确保该值适合签名的长整数.

这一切都运行良好(太大的值导致编译错误),但只有当我明确创建一个变量,如

constexpr auto a= 150_X;
Run Code Online (Sandbox Code Playgroud)

相反,我会写一些典型的东西

cout << 150_X << endl;;
Run Code Online (Sandbox Code Playgroud)

测试不在编译时执行.

  • constexpr函数是否仅在编译时执行,如果它们被分配给constexpr变量?(我在标准中找不到)

  • 是否有可能实现_X我正在寻找的安全行为?

完整示例:

#include<iostream>
#include<stdexcept>

inline constexpr long long testConv(unsigned long long v) {
  return (v > 100 ) ? throw std::exception() : v; 
} // will eventually use actual limit from numeric_limits

inline constexpr long long operator "" _X(unsigned long long f) { 
  return testConv(f) ;
}

int main(){
  constexpr auto a= …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

7
推荐指数
1
解决办法
2304
查看次数

返回C++ 17可变参数模板'构造演绎指南'的可变参数聚合(结构)和语法

使用many如下所示的模板结构,可以返回一组固定的可能不可移动的对象,并使用c ++ 17结构化绑定接收它们(auto [a,b,c] = f();声明变量ab和c并从f返回它们的值,例如结构或元组).

template<typename T1,typename T2,typename T3>
struct many {
  T1 a;
  T2 b;
  T3 c;
};

// guide:
template<class T1, class T2, class T3>
many(T1, T2, T3) -> many<T1, T2, T3>;

auto f(){ return many{string(),5.7, unmovable()}; }; 

int main(){
   auto [x,y,z] = f();
}
Run Code Online (Sandbox Code Playgroud)

正如在这两个问题和答案中所解释的那样(Do std :: tuple和std :: pair是否支持聚合初始化? 特别是ecatmur接受的答案,还有多个返回值(结构化绑定)和不可移动的类型以及C++中保证的RVO 17),std::tuple不支持聚合初始化.这意味着它不能用于保存和返回不可移动的类型.但是一个简单的结构many可以做到这一点,这导致了一个问题:

是否可以创建一个many可以使用任意数量参数的可变版本?

更新:在模板版本中many,是否允许使用以下指南语法?

template<typename Args...>    
many(Args...) -> many<Args...>;
Run Code Online (Sandbox Code Playgroud)

c++ templates c++17

7
推荐指数
1
解决办法
1139
查看次数

如何将back_inserter与转换C++结合起来

如何包装OutputIterator,例如back_inserter_iterator转换?考虑

std::vector<double> xx;
std::vector<double> yy;
std::vector<double> diff;
auto ba = std::back_inserter(diff);
std::set_difference(xx.begin(), xx.end(), yy.begin(), yy.end(), ba);
Run Code Online (Sandbox Code Playgroud)

我想应用一个自由函数f(double)g(std::vector<double>::iterator)在推回到diff矢量之前:

具体来说,我如何存储diff元素(或迭代器)的地址而不是元素本身.

std::vector<double&> diff;
auto baAdr = ??? std::back_inserter( ??? (diff)); 
std::set_difference(xx.begin(), xx.end(), yy.begin(), yy.end(), baAdr);
Run Code Online (Sandbox Code Playgroud)

出于性能原因(真实数据很大),我不想构建一个临时向量std::transform.它也不适用于不可复制的可移动类型.

我可以用boost.

c++ boost iterator c++14

7
推荐指数
1
解决办法
543
查看次数

为什么无序关联容器不使用C++ 0x中的allocator_traits <T>

为什么C++ 0x无序关联容器不使用allocator_traits来定义它们的成员类型指针和const_pointer?

例如,顺序和有序关联容器使用以下定义:

typedef typename allocator_traits<Allocator>::pointer pointer;
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
Run Code Online (Sandbox Code Playgroud)

而无序的关联容器使用这个:

typedef typename Allocator::pointer pointer;
typedef typename Allocator::const_pointer const_pointer;
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

c++ containers c++11

6
推荐指数
1
解决办法
260
查看次数

使用模板构造函数创建模板类对象

我在从模板类创建类对象时遇到问题,在模板类中我需要构造函数也是模板并在创建对象时接受参数.但是,当我尝试创建对象时,我收到一条错误消息,指出我引用了一些不存在的内容.

这是我的代码:

using namespace std;
#include <cstdlib>

template <class Node_Type>
class BinaryTree 
{
public:
    BinaryTree(Node_Type);
    BinaryTree(Node_Type, Node_Type);
    BinaryTree(Node_Type, Node_Type, Node_Type);
    bool isEmpty();
    Node_Type info();
    Node_Type inOrder();
    Node_Type preOrder();
    Node_Type postOrder();


private:
    struct Tree_Node
{
    Node_Type Node_Info;
    BinaryTree<Node_Type> *left;
    BinaryTree<Node_Type> *right;
};

Tree_Node *root;

};

#endif
Run Code Online (Sandbox Code Playgroud)

和我的.cpp:

template <class Node_Type>
BinaryTree<Node_Type>::BinaryTree(Node_Type rootNode) {

    root = rootNode;
    root->left = NULL;
    root->right = NULL;

}
Run Code Online (Sandbox Code Playgroud)

.cpp还有更多,但它只是其他功能成员无关紧要.我上面显示的构造函数是我无法工作的.

在我的主要内容中,我试图通过调用声明我的对象:

BinaryTree<char> node('a');
Run Code Online (Sandbox Code Playgroud)

但是当我尝试这个时,我收到一条错误消息,指出:

undefined reference to `BinaryTree<char>::BinaryTree(char)'
Run Code Online (Sandbox Code Playgroud)

我一直试图解决这个问题两天了.我用Google搜索了我能想到的每个主题,并在Stack Overflow和其他来源上阅读了无数的例子,没有任何帮助.谁能解释一下我的问题是什么?我知道如何完成我的项目,如果语法在C++中不那么荒谬,我现在就完成了.提前致谢!

c++ templates constructor class

6
推荐指数
2
解决办法
2万
查看次数

从初始化列表中启动向量时,为什么不使用移动构造(通过隐式构造函数)

为了演示移动语义,我使用int中的隐式构造函数编写了以下示例代码.

struct C {
  int i_=0;
  C() {}
  C(int i) : i_( i ) {}
  C( const C& other) :i_(other.i_) {
    std::cout << "A copy construction was made." << i_<<std::endl;
  }
  C& operator=( const C& other) {
    i_= other.i_ ;
    std::cout << "A copy assign was made."<< i_<<std::endl;
    return *this;
  }
  C( C&& other ) noexcept :i_( std::move(other.i_)) {
    std::cout << "A move construction was made." << i_ << std::endl;
  }
  C& operator=( C&& other ) noexcept {
    i_ = …
Run Code Online (Sandbox Code Playgroud)

c++ initializer-list move-semantics c++14

6
推荐指数
1
解决办法
455
查看次数

在具有固定常数离散的给定网格上与c ++进行数值积分

我有以下问题:

我的c ++代码可以计算两个函数

F1(I1,I2,I3,I4)

F2(J1,J2)

对于{i1,i2,i3,i4}的每一组,我得到一些f1值,对于{j1,j2}的每一组,我得到一些f2的值.

集合{i1,i2,i3,i4}和{j1,j2}在FIXED网格上给出,具有一些恒定的离散化步骤"h".

我需要用数学语言计算积分F3(x1,x3)=积分[f1(x1,x2,x3,x4)*f2(x3,x4)dx3 dx4]

简单求和不够好,因为f2有很多跳跃.

是否有一些c ++库可以进行这种集成?或者一些易于实现的算法(我对c ++并不擅长)

非常感谢

c++ algorithm math integration numerics

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

没有编译器警告错误的支撑初始化程序

UPDATE2:

怀疑,这与初始化列表构造函数没有关系.根据R. Martinho Fernandes的评论,很明显它只是试图构造一个带有自身副本的对象,这个对象在使用大括号语法时未被检测到:

struct C{
   C(){}   
};
struct D{
   C c0{c0};  // << -- compiles without warning
   C c1(c1);  // << -- does not compile
};
Run Code Online (Sandbox Code Playgroud)

问题仍然存在.这种情况下标准是否需要诊断?我确实意识到诊断不可能或不适用于各种错误.

我最后报告了这个,因为错误57758.

原始问题:

我知道的人设法编写错误的代码(由纯错误引起),最终产生虚假bad_alloc异常.我想知道gcc(4.7.2和4.8.1)是否有充分的理由不对此发出警告.

这种情况下标准是否需要诊断?我确实意识到诊断不可能或不适用于各种错误.

这就是它归结为:

#include <initializer_list>
struct A{};
struct C{
   C(std::initializer_list<A*> as){}   
};
struct D{
   C c{c}; // <<- well...
};    
int main(){
   D d;
}
Run Code Online (Sandbox Code Playgroud)

编辑:我提到的原因initializer_list是,如果我删除初始化列表构造函数,我会收到一个错误:error: too many initializers for ‘C’

我认为是由于没有用户定义的(用户声明的?)构造函数,我得到了聚合初始化,由于C中没有成员(C类型),因此无法工作.

c++ gcc

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

memmove有效类型的原位变更(类型 - 双关语)

在下面的问题中: 什么是将一个浮点数类型化为int的正确方法,反之亦然?,结论是从整数位构造双精度的方法,反之亦然memcpy.

那很好,pseudo_cast转换方法有:

template <typename T, typename U>
inline T pseudo_cast(const U &x)
{
    static_assert(sizeof(T) == sizeof(U));    
    T to;
    std::memcpy(&to, &x, sizeof(T));
    return to;
}
Run Code Online (Sandbox Code Playgroud)

我会像这样使用它:

int main(){
  static_assert(std::numeric_limits<double>::is_iec559);
  static_assert(sizeof(double)==sizeof(std::uint64_t));
  std::uint64_t someMem = 4614253070214989087ULL;
  std::cout << pseudo_cast<double>(someMem) << std::endl; // 3.14
}
Run Code Online (Sandbox Code Playgroud)

我只是阅读标准和cppreference的解释是,也应该可以用来就地memmove改变有效类型,如下所示:

template <typename T, typename U>
inline T& pseudo_cast_inplace(U& x)
{
    static_assert(sizeof(T) == sizeof(U));
    T* toP = reinterpret_cast<T*>(&x);
    std::memmove(toP, &x, sizeof(T));
    return *toP;
}

template <typename T, typename U> …
Run Code Online (Sandbox Code Playgroud)

c++ type-punning

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