标签: initializer-list

可选地支持模板的initializer_list构造可能包装容器

如果我有一个包装标准容器的模板,似乎我可以合理地轻松委托initializer_list构造函数:

template<typename T>
struct holder {
    T t_;

    holder() :
        t_() {}

    holder(std::initializer_list<typename T::value_type> values)
        : t_(values) {}

};
Run Code Online (Sandbox Code Playgroud)

因此,这与std :: vector很好地配合.

int main(int argc, char* argv[]) {

    holder<std::vector<int>> y{1,2,3};
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

但它很明显不适用于T作为'int',或任何其他没有嵌套value_type typedef的类型.所以,我想使用某种enable_if或类似技巧来使initializer_list构造函数不被发出,除非T都定义了嵌套的value_type typedef,并且可以从std :: initializer_list构造.

我尝试了下面这个,但它仍然不起作用,因为编译器(在我的情况下是clang ++ 3.1),当T为int时仍会跳过无效的T :: value_type:

holder(typename std::enable_if<std::is_constructible<T, std::initializer_list<typename T::value_type>>::value, std::initializer_list<typename T::value_type>>::type values)
    : t_(values) {}
Run Code Online (Sandbox Code Playgroud)

关于如何表达概念的任何想法"在T的value_type上给这个模板提供初始化列表构造函数,当且仅当T具有value_type typedef且可从T :: value_type的initializer_list构造时".

c++ templates initializer-list enable-if c++11

10
推荐指数
1
解决办法
667
查看次数

将Variadic模板包转换为std :: initializer_list

假设有一个接受多个字符串的函数:

void fun (const std::initializer_list<std::string>& strings) {
  for(auto s : strings)
    // do something
}
Run Code Online (Sandbox Code Playgroud)

现在,我有一个可变template函数说foo():

template<typename ...Args>
void foo () {
  fun(???);
}
Run Code Online (Sandbox Code Playgroud)

此方法在外部称为:

foo<A, B, C, D>(); // where A, B, C, D are classes
Run Code Online (Sandbox Code Playgroud)

这些作为参数传递的类应该包含一个公共static const成员:

static const std::string value = "...";
Run Code Online (Sandbox Code Playgroud)

以下是我的问题(如何):

  1. 在里面foo(),检查是否所有Args包含value使用 static_assert
  2. 将所有这些值传递fun()给形成initializer_list; 例如 fun({A::value, B::value, ...});

搜索了几个与可变参数模板及其解包相关的线程,但我仍然是这个领域的新手.非常感谢更详细的解释.

c++ templates initializer-list variadic-templates c++11

10
推荐指数
1
解决办法
3919
查看次数

使用大括号括起初始化列表初始化struct vector

我初始化这样的普通类型向量:

vector<float> data = {0.0f, 0.0f};
Run Code Online (Sandbox Code Playgroud)

但是当我使用结构而不是普通类型时

struct Vertex
{
    float position[3];
    float color[4];
};
vector<Vertex> data = {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}};
Run Code Online (Sandbox Code Playgroud)

我收到错误could not convert '{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}}' from '<brace-enclosed initializer list>' to 'std::vector<Vertex>'.这有什么问题?

c++ struct vector initializer-list c++11

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

无法将多个初始化程序列表传递给可变参数函数模板

尝试传递可变数量的初始化列表时,我不明白错误消息:

template<typename... Values>
void foo(Values...)
{
}

int main()
{
    foo(1, 2, 3, "hello", 'a');   // OK

    foo({1}, {2, 3});             // ERROR
}
Run Code Online (Sandbox Code Playgroud)

错误消息抱怨参数太多:

prog.cpp: In function ‘int main()’:
prog.cpp:9:20: error: too many arguments to function
                      ‘void foo(Values ...) [with Values = {}]’
     foo({1}, {2, 3});
                    ^
prog.cpp:2:6: note: declared here
 void foo(Values...)
      ^
Run Code Online (Sandbox Code Playgroud)

但是,我是否应该无法传递尽可能多的参数?[ 意见链接 ]

c++ templates initializer-list variadic-templates c++11

10
推荐指数
2
解决办法
1710
查看次数

为什么`vector <int> v {{5,6}};`工作?我以为只允许一对{}被允许?

给定一个A带有两个构造函数的类,分别取initializer_list<int>initializer_list<initializer_list<int>>

A v{5,6};
Run Code Online (Sandbox Code Playgroud)

叫前者,和

A v{{5,6}};
Run Code Online (Sandbox Code Playgroud)

按预期调用后者.(clang3.3,显然gcc表现不同,请看答案.标准需要什么?)

但是如果我删除第二个构造函数,那么A v{{5,6}};仍然编译并使用第一个构造函数.我没想到这一点.我认为这A v{5,6}将是访问构造函数的唯一方法initializer_list<int>.

(我发现这一点的同时与玩弄std::vector这个问题,我问在Reddit上,但我创建了自己的A级,以确保它不只是一个对接口的怪癖std::vector.)

initializer-list c++11

10
推荐指数
1
解决办法
250
查看次数

是否可以初始化const Eigen矩阵?

我有以下课程:

class Foo
{
public:
   Foo(double a, double b, double c, double d, double e)
   // This does not work:
   // : m_bar(a, b, c, d, e)
   {
      m_bar << a, b, c, d, e;
   }

private:
   // How can I make this const?
   Eigen::Matrix<double, 5, 1, Eigen::DontAlign> m_bar;
};
Run Code Online (Sandbox Code Playgroud)

我如何制作m_bar const并将其初始化为a到f作为构造函数中的值?C++ 11也没问题,但初始化程序列表似乎不受eigen支持...

c++ constructor const initializer-list eigen

10
推荐指数
2
解决办法
3648
查看次数

初始化列表与向量

在C++ 11中,可以使用初始化列表来初始化函数中的参数.它的目的是什么?使用const向量不能做同样的事情吗?以下两个程序有什么区别?

使用初始化列表:

#include <iostream>

using namespace std;

int sumL(initializer_list<int> l){
    int sum = 0;
    for (const auto i: l){
        sum += i;
    }
    return sum;
}

int main(){

    cout << sumL({1, 2, 3}) << "\n";

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用const向量:

#include <iostream>
#include <vector>

using namespace std;

int sumV(const vector<int> l){
    int sum = 0;
    for (const auto i: l){
        sum += i;
    }
    return sum;
}

int main(){

    cout << sumV({1, 2, 3}) << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ initialization vector initializer-list c++11

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

初始化列表中的const引用成员的初始化

我正在玩一些无用的代码来理解成员引用的初始化,并碰到了这个:

struct A {};

struct B
{
    B() : a()
    {
    }

    const A& a;
};
Run Code Online (Sandbox Code Playgroud)

使用gcc 4.9.2编译时,上面的代码给出以下错误:

In constructor 'B::B()':
error: value-initialization of reference type 'const A&'
  B() : a()
Run Code Online (Sandbox Code Playgroud)

我明白了

但是如果我在B的​​构造函数的初始化列表中使用统一初始化,就像这样:

struct A {};

struct B
{
    B() : a{}
    {
    }

    const A& a;
};
Run Code Online (Sandbox Code Playgroud)

它汇编很好.

所以问题是,为什么在这里使用统一初始化会改变编译结果?

我也尝试使用Microsoft Visual C++ 2013.它不编译任何版本的代码,并使用相同的错误消息:

Error 3 error C2440: 'initializing' : cannot convert from 'int' to 'const A & 
Run Code Online (Sandbox Code Playgroud)

你可以在这里快速玩它:

http://ideone.com/7f2t8I

c++ gcc initialization reference initializer-list

10
推荐指数
1
解决办法
1245
查看次数

带有初始化列表的C++的max()不按顺序返回字符串

max({"a", "b", "z", "x"});  returns "x"
Run Code Online (Sandbox Code Playgroud)

两者都有

max<std::string>({"a", "b", "z", "x"});
Run Code Online (Sandbox Code Playgroud)

max({'a', 'b', 'z', 'x'});
Run Code Online (Sandbox Code Playgroud)

按原样返回"z".为什么?

c++ string max initializer-list c++11

10
推荐指数
2
解决办法
550
查看次数

C ++ std :: vector initializer_list重载歧义(g ++ / clang ++)

考虑以下代码:

#include <vector>

#define BROKEN

class Var {
public:
#ifdef BROKEN
    template <typename T>
    Var(T x) : value(x) {}
#else
    Var(int x) : value(x) {}
#endif

    int value;
};

class Class {
public:
    Class(std::vector<Var> arg) : v{arg} {}

    std::vector<Var> v;
};
Run Code Online (Sandbox Code Playgroud)

不管是否BROKEN定义,Clang ++(7.0.1)都会编译此错误,而如果BROKEN已定义,则g ++(8.2.1)会引发错误:

main.cpp:9:20: error: cannot convert ‘std::vector<Var>’ to ‘int’ in initialization
  Var(T x) : value(x) {}
                    ^
Run Code Online (Sandbox Code Playgroud)

据我所知,std::vector(std::vector&&)在两种情况下,这里使用的统一初始化都应选择构造函数。但是,显然,g++它将{arg}视为初始化列表,并尝试初始化应用于向量的vwith 的第一个元素Var,这将不起作用。

如果BROKEN未定义,则g ++显然足够聪明,可以意识到initializer_list重载将无法正常工作。

哪个是正确的行为,或者标准都允许? …

c++ stdvector initializer-list uniform-initialization

10
推荐指数
1
解决办法
192
查看次数