在另一个话题中 ,@Dietmar给出了这个解决scheme: template <typename… T> std::tuple<T…> parse(std::istream& in) { return std::tuple<T…>{ T(in)… }; } 说明, 使用大括号初始化工作是因为大括号初始化符列表中的参数的评估 顺序是它们出现的顺序 。 (强调我的) C ++标准(n3485)的相关文本是, 在braced-init-list的初始化程序列表中,初始化程序子句(包括从程序包扩展(14.5.3)产生的任何子程序子句)按其出现的顺序进行评估。 也就是说,与给定初始化子句相关联的每个值计算和副作用在与初始值设定项列表的逗号分隔列表中的任何初始化子句相关联的每个值计算和副作用之前被sorting。 [注意:不pipe初始化的语义如何,这个评估顺序都是成立的。 例如,当初始化列表的元素被解释为构造函数调用的参数时,即使通常对调用的参数没有sorting约束,也适用。 – 注意] 所以我试图用下面的代码来testing它: template<int N> struct A { std::string data; A(std::istream & stream) { stream >> data; } friend std::ostream& operator<<(std::ostream & out, A<N> const & a) { return out […]
编辑,为了避免混淆: decltype不接受两个参数。 查看答案。 在编译期间,可以使用以下两个结构来检查typesT上成员函数的存在: // Non-templated helper struct: struct _test_has_foo { template<class T> static auto test(T* p) -> decltype(p->foo(), std::true_type()); template<class> static auto test(…) -> std::false_type; }; // Templated actual struct: template<class T> struct has_foo : decltype(_test_has_foo::test<T>(0)) {}; 我认为这个想法是在检查成员函数的存在时使用SFINAE,所以在p->foo()无效的情况下,只定义返回std::false_type的test的椭圆版本。 否则,第一个方法被定义为T* ,并将返回std::true_type 。 实际的“开关”发生在第二个类中,它inheritance自test返回的types。 与is_same等不同的方法相比,这看起来很聪明和“轻量级”。 有两个参数的decltype首先让我感到惊讶,因为我认为它只是得到了一个expression式的types。 当我看到上面的代码时,我认为它是“试图编译expression式,并总是返回第二种types,如果expression式编译失败,则失败”(所以隐藏这个特殊化; SFINAE)。 但: 然后我想我可以用这个方法来写任何“有效的expression式”检查器,只要它依赖于某种types的T 例: … template<class T> static auto […]
C ++ 11标准对于标准库的自动分配有什么意义? 更具体一些,如果有的话,什么是selfAssign保证什么? template<class T> std::vector<T> selfAssign(std::vector<T> v) { v = std::move(v); return v; }
给出以下代码: struct A { static constexpr int a[3] = {1,2,3}; }; int main () { int a = A::a[0]; int b [A::a[1]]; } A::a必然odr-用于 int a = A::a[0] ? 注意:这个问题代表了rest室里一个不那么有争议/不合逻辑的辩论 。
是否有可能根据C ++ 11expression式是否是C ++ 11中的常量expression式(即constexpr )来生成编译时布尔值? 关于这个问题的几个问题与此有关,但我没有在任何地方看到明确的答案。
我正在创build一个函数(可能是成员函数,不是那么重要,也许它是这样做的),它需要接受未知数量的参数,但是我希望所有的参数都是相同的types。 我知道我可以通过一个数组或向量,但我希望能够直接接受参数的列表,没有额外的结构,甚至额外的括号。 它看起来不像variadic函数本身是types安全的,我不知道如何去做这个w / variadic模板函数。 这里基本上是我的目标(更可能不正确的代码,完全不是为了获得龙列表,哈哈): //typedef for dragon_list_t up here somewhere. enum Maiden { Eunice , Beatrice , Una_Brow , Helga , Aida }; dragon_list_t make_dragon_list(Maiden…) { //here be dragons } 要么 template<Maiden… Maidens> dragon_list_t make_dragon_list(Maidens…) { //here be dragons } 用法 dragon_list_t dragons_to_slay = make_dragon_list(Maiden.Eunice, Maiden.Helga, Maiden.Aida) ; 试了几件与上面类似的东西,没有骰子。 build议? 我可能做出的明显疏忽? 我知道这样做可能不是一个大问题: dragon_list_t […]
我今天在想我的同事是否可以实现std :: vector来利用小缓冲区优化。 通过查看C ++ 11草案,我在23.3.1p8阅读 对于非数组的标准容器types的容器a和b,expression式a.swap(b)应交换a和b的值,而不对每个容器元素调用任何移动,复制或交换操作。 起初似乎取消了小缓冲区优化,但是在as-if规则下,我们仍然可以为非类types进行小缓冲区优化(因为我们无法观察正在执行的副本)。 接下来的文字似乎更难以“愚弄” 每个在交换之前引用一个容器中的元素的迭代器应该在交换之后引用另一个容器中的相同元素。 这足以防止实施std :: vector的小缓冲区优化? 有没有其他的路障,或者最终是否有可能有SBO的std :: vector?
“ 有效的C ++ ”第3项说“尽可能使用常量”,它给出了一个例子: const Rational operator*(const Rational& lhs, const Rational& rhs); 防止客户犯下这样的暴行: Rational a, b, c; … (a * b) = c; // invoke operator= on the result of a*b! 但不是函数的非参考返回值已经是右值 ? 那么为什么要这样做呢?
我正在阅读C ++ Primer,当expression式产生一个对象types,并产生一个对象的引用types时,我不太明白。 我引用这本书: 当我们将decltype应用于不是variables的expression式时,我们得到expression式产生的types。 一般来说,decltype会返回一个expression式的引用types,这些expression式会产生可以位于赋值左侧的对象。 考虑下面的代码: int i = 3, *ptr = &i, &ref = i; decltype(ref + 0) j; 在上面的代码中,expression式“ref + 0”产生了ref引用的对象的值i和0的附加值的固有操作。因此,按照第一个规则,expression式产生一个inttypes。 但是按照第二条规则,因为expression式产生了一个可以站在赋值左边的对象的types(在本例中为int),decltype不应该产生一个int(int&)types的引用吗? 这本书还说,下面的代码 decltype(*ptr) k; k的types是int&而不是int,expression式的结果types。 它还表示,像下面的代码中的分配expression式 decltype(a = b) l; l将在赋值操作的左侧具有对象的引用types。 我们如何知道哪些expression式产生对象types,哪些产生对对象types的引用?
今天我跑了一个非常微妙的问题,我想请你的意见。 考虑以下花园式的共同成语成语课: struct S { S() : p_impl(new impl) {} private: struct impl; boost::shared_ptr<impl> p_impl; }; 当你试图用下列方法把它们放到vector中时,乐趣就会出现: std::vector<S> v(42); 现在,至less在MSVC 8中, v所有元素共享相同的impl成员。 其实,是什么导致这是vector构造函数: template <typename T, typename A = …> class vector { vector(size_t n, const T& x = T(), const A& a = A()); … }; 在场景下,只有一个S对象被默认构造, vector的n元素被复制。 现在,用C ++ 11,有右值引用。 所以它不能这样工作。 如果一个vector被构造成 std::vector<S> […]