相关疑难解决方法(0)

C++ 11 - constexpr函数中的static_assert?

如何static_assert在一个constexpr函数中正确执行?例如:

constexpr int do_something(int x)
{
  static_assert(x > 0, "x must be > 0");
  return x + 5;
}
Run Code Online (Sandbox Code Playgroud)

这不是有效的C++ 11代码,因为constexpr函数必须只包含return语句.我不认为该标准有例外,但GCC 4.7不允许我编译这段代码.

c++ static-assert constexpr c++11

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

为什么size不是std :: initializer_list的模板参数?

std::initializer_list 由编译器从大括号括起的init列表构造,并且该列表的大小必须是编译时常量.

那么为什么委员会决定从模板参数中省略大小呢?这可能会阻止一些优化并使一些事情变得不可能(std::array从a 初始化std::initializer_list).

c++ initializer-list c++11

17
推荐指数
2
解决办法
1874
查看次数

有没有办法强制执行std :: array的完全初始化

我正在使用std::array<size_t, N>(N是一个固定的模板变量).

#include<array>
template<size_t N>
struct A{
   size_t function(std::array<size_t, N> arr){ return arr[N-1];} // just an example
};

int main(){
   A<5> a;
   a.function({{1,2,3,4,5}}));
}
Run Code Online (Sandbox Code Playgroud)

它工作正常.问题是这个其他代码是默默允许的:

   A.function({{1,2,3}}));
Run Code Online (Sandbox Code Playgroud)

也就是说,即使错过了元素,也会以array某种方式初始化,即使它被很好地定义(例如,剩余元素初始化为零,我不确定)这可能是错误的来源.

有没有办法强制执行额外元素的初始化?例如,通过生成编译器错误或警告.

我想到的一个选择是使用 initializer_list

   size_t function2(std::initializer_list<size_t> il){ assert(il.size() == N); ...}
Run Code Online (Sandbox Code Playgroud)

问题是,这最多会产生运行时错误并检查每次调用.我更喜欢编译器错误/警告.

我没有受到默认初始化的困扰,std::array<>{}而是由不完整的初始化所困扰.(也许没有什么可以做的,因为这是从T[N]静态数组的行为继承而来的.)

我试过用clang 3.5gcc 5.

arrays initialization c++11 stdarray

9
推荐指数
2
解决办法
482
查看次数

在编译时验证std :: initializer_list的内容

我试图在编译时确定a std::initializer_list中的所有值是否唯一.我找到了一个解决方案,以确定列表的大小,但无法将其应用于内容.我已尝试使用自由函数和构造函数,但这两种方法都导致GCC 4.7.2出现以下错误.

错误:静态断言
错误的非常量条件:'begin'不是常量表达式

我意识到std::initializer_list没有声明成员,constexpr但我希望有一个像尺寸验证的解决方案.是否可以使用以下内容在编译时验证内容?

#include <initializer_list>

template<typename InputIterator>
constexpr bool Validate(InputIterator begin, InputIterator end)
{
    static_assert(*begin == *end, "begin and end are the same");
    //  The actual implemetnation is a single line recursive check.
    return true;
}

template<typename InputType>
constexpr bool Validate(const std::initializer_list<InputType>& input)
{
    // "-1" removed to simplify and eliminate potential cause of error
    return Validate(input.begin(), input.end() /* - 1 */);
}

int main()
{
    Validate({1, 2, 1});
}
Run Code Online (Sandbox Code Playgroud)

c++ validation initializer-list constexpr c++11

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

是否可以从大括号类型初始化推断元组的模板参数?

在这个例子中,是否可以允许推导 的模板参数类型tuple

#include<tuple>
#include<string>

template<class T1, class T2>
void fun(std::tuple<T1, T2> t, std::string other){}

int main(){
    fun(std::tuple<double, int>(2.,3), std::string("other")); // ok
    fun(std::make_tuple(2.,3), std::string("other")); // ok, but trying to avoid `make_tuple`
    fun({2.,3},std::string("other")); // desired syntax but
    // giving compilation error: candidate template ignored: couldn't infer template argument 'T1' void fun(std::tuple<T1, T2> t)
}
Run Code Online (Sandbox Code Playgroud)

我添加了第二个参数,other以避免涉及函数级别的可变参数的解决方案fun。另外,我试图避免使用make_tuple,至少在用户代码中(即在main())。事实上,它不需要是tuple所涉及的类型,只要允许“所需的语法”,并且可以在稍后阶段以某种方式推断出其元素类型。

(另外,虽然相似,但这无关,initializer_list因为它在大括号中具有不同的元素根本不起作用)

它至少在clang 3.2和时失败gcc 4.7.2。它是否有希望与当前或不久的将来的标准兼容?(例如未来(?)initializer_tuple。)

(这对于通过聚合子元素来增加函数调用的表现力非常有用,但这可以争论)


注意:对于示例代码,似乎std::forward_as_tuple …

c++ tuples explicit copy-initialization c++11

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