2

我想通过一些数字字节值初始化列表一个可变参数模板到一个数组中。那可能吗?

template < int N > struct a {
  char s[N];
  template < typename ... A >
  a (A ... _a) : s {_a...} {}
};

int main () {
  // g++-4.5: error: narrowing conversion of »_a#0« from »int« to »char« inside { }
  a < 3 > x { 1, 2, 3 };
}

我能想到的是

  • 使用八进制表示,'\001' 等,或
  • 转换每一个值。

但两者都不令人满意。

4

3 回答 3

2

你不需要任何复杂的代码

template < int N > struct a {
  char s[N];
  template < typename ... A >
  a (A ... _a) : s {static_cast<char>(_a)...} {}
};
于 2011-01-14T12:31:00.143 回答
0

注意:所有这些都是不必要的,除非您向类添加了功能,因此它不再是聚合。(例如,其他构造函数、私有成员、基类等)修复问题中的代码的直接方法是删除构造函数。所以,让我们假设它还有更多内容。

我见过一些人试图做这样的事情。处理转换语义并尝试人为地重新创建通常函数调用的功能似乎很难看。

这是一种创建数组类的策略,它首先具有正确的构造函数。

模板别名会通过隐藏丑陋来锦上添花::type,但它还没有在 GCC 中。

template< typename ... NT >
struct var_ctor_array {
    enum { size_e = 0 }; // only used for zero size case
};

template< typename T, typename ... NT >
struct var_ctor_array< T, NT ... > {
    enum { size_e = 1 + sizeof...( NT ) };

    T st[ size_e ];

    var_ctor_array( T elem0, NT ... elemN )
        : st { elem0, elemN ... } {}
};

template< typename T, size_t N, typename ... NT >
struct gen_var_ctor_array {
    typedef typename gen_var_ctor_array< T, N-1, T, NT ... >::type type;
};

template< typename T, typename ... NT >
struct gen_var_ctor_array< T, 0, NT ... > {
    typedef var_ctor_array< NT ... > type;
};

int main() { // usage
    gen_var_ctor_array< char, 5 >::type five( 1, 2, 3, 4, 5 );
}
于 2010-09-16T04:59:17.877 回答
0

您实际上并没有使用初始化列表。构造函数接收一个可变参数模板,并x使用统一初始化进行初始化

唯一的问题是我不知道用 初始化数组的优雅方法initializer_list,AFAIKstd::array应该有一个可以接受的构造函数,initializer_list但 g++ 似乎还不支持它。

#include <utility>
template < int N > struct a {
    char s[N];

    a (std::initializer_list<char> list) {
        if (N != list.size()) 
            throw "list wrong size";

        int i = 0;
        const char* p = list.begin();
        while(p != list.end())
            s[i++] = *p++;
    }
};
于 2010-09-15T19:00:40.113 回答