聚合初始化除其他外不需要用户提供的构造函数.但是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).
是tuple与pair特殊标准语言的支持,让这(在构造函数中的存在)?:
20.5.2.1施工
... EXPLICIT constexpr元组(const类型&...);
6效果:构造函数使用相应参数的值初始化每个元素.
或者我们原则上可以自己编写tuple或者pair?
更新:我下面贴我自己的答案 在这里,还有这件事情更长的版本: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) 使用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) 如何包装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++ 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)
我错过了什么?
我在从模板类创建类对象时遇到问题,在模板类中我需要构造函数也是模板并在创建对象时接受参数.但是,当我尝试创建对象时,我收到一条错误消息,指出我引用了一些不存在的内容.
这是我的代码:
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++中不那么荒谬,我现在就完成了.提前致谢!
为了演示移动语义,我使用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 ++代码可以计算两个函数
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 ++并不擅长)
非常感谢
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类型),因此无法工作.
在下面的问题中:
什么是将一个浮点数类型化为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++ ×10
c++11 ×2
c++14 ×2
c++17 ×2
templates ×2
aggregate ×1
algorithm ×1
boost ×1
class ×1
constexpr ×1
constructor ×1
containers ×1
gcc ×1
integration ×1
iterator ×1
math ×1
numerics ×1
std-pair ×1
tuples ×1
type-punning ×1