标签: static-assert

static_assert失败检查模板化对象指针

template <size_t N>
class Foo
{
    static_assert(N > 0, "WRONG");
    //void Something() = 0; //my original implementation
};

int main() {

    Foo<0> *p2 = nullptr;   //no error
    Foo<0> p;   //gives an error

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

我已分别测试了两条线.初始化p2时不调用static_assert但是它被调用并确实在p上失败.这是有意的吗?(我在gcc,clang和VC上尝试过)

解决方法有哪些?由于我正在使用抽象模板化类,如果断言仅在实例化非指针对象时执行,那将是一场噩梦.我可以使用工厂,但这不是一个合适的解决方案.

c++ templates static-assert assertions c++11

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

如何在模板变量定义中引入static_assert

如何引入static_assert模板变量定义?

我的尝试是使用 lambda 函数:

#include <type_traits>
#include <utility>

#include <cstdlib>

namespace
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wglobal-constructors"

template< typename F >
F f = ([] () { static_assert(std::is_default_constructible< F >{}); }(), F{});

#pragma clang diagnostic pop
}

struct L
{
    L() = default;
    L(L const &) = delete;
    L(L &&) = delete; 
};

int
main()
{
    static_cast< void >(f< L >);
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

但对于不可移动的对象,不可能以这种方式构造值对象。

使用逗号运算符我无法在 form 中执行值初始化F f = ([] () { …

c++ static-assert type-traits variable-templates c++14

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

如果compile-time-constant参数错误,则生成编译时错误

我正在尝试编写一个函数,如果使用编译时常量参数调用它将触发编译时错误,如果参数的值与a不匹配static_assert,但仍然可以在运行时使用计算值调用.

有点像这样:

template<int N> void f(N){
  static_assert(N == 5, "N can only be 5.");
  do_something_with(N);
}

void f(int N){
  if(N == 5){
    do_something_with(N);
  }
}

volatile int five = 5;
volatile int six = 6;

int main() {  
  f(5); //ok
  f(6); //compile-time error
  f(five); //ok
  f(six); //run-time abort

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

我怎样才能做到这一点?

此外,如果可能的话,我希望能够保留简单的f(something)语法,因为此代码适用于不熟悉模板语法的初学者程序员可以使用的库.

c++ templates overloading static-assert c++11

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

编译时间断言不可靠?

我正在阅读《现代C ++设计》一书的第一章。特别是,编译时间断言。我的以下代码有问题:

template<bool> struct CompileTimeChecker
{
  CompileTimeChecker(...) {}
};

template<> struct CompileTimeChecker<false> {};

#define STATIC_CHECK(expr, msg)\
{\
  struct ERROR_##msg {ERROR_##msg() {}};\
  CompileTimeChecker<((expr) != 0)>(ERROR_##msg());\
}

int main()
{
  STATIC_CHECK(0, MessageNull);
  STATIC_CHECK(1, MessageOne);
}
Run Code Online (Sandbox Code Playgroud)

对于g ++ 7.4.0和clang ++ 6.0.0,这不会引发编译时错误。但是,以下代码确实引发了错误(按预期):

template<bool> struct CompileTimeChecker
{
  CompileTimeChecker(...) {}
};

template<> struct CompileTimeChecker<false> {};

#define STATIC_CHECK(expr, msg)\
{\
  struct ERROR_##msg {ERROR_##msg(int i) {i;}};\
  CompileTimeChecker<((expr) != 0)>(ERROR_##msg(0));\
}

int main()
{
  STATIC_CHECK(0, MessageNull);
  STATIC_CHECK(1, MessageOne);
}
Run Code Online (Sandbox Code Playgroud)

第二个代码的唯一区别是带有参数的构造函数的用法。


在两种情况下,预期的错误消息是:

  • g ++: no matching function for call to …

c++ static-assert

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

检查指定给std :: array编译时间的元素数

我有一个性能关键代码,可以查询N个索引。如何static_assert在不牺牲性能的情况下检查是否给出了准确的N个索引?

#include <array>

template<int N>
void test(const std::array<int, N>& indices)
{
    // static_assert:  has three elements.
    return;
}

int main()
{
    test<3>({1, 2, 3}); // OK
    test<3>({1, 2});    // Needs to crash, because 2 < 3

    test<2>({1, 2, 3}); // Crashes, because 3 > 2
    test<2>({1, 2});    // OK

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

c++ static-assert stdarray

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

如何在 constexpr if-else 链中导致静态错误?

在以下 C++20 函数模板中:

template<int i>
void f() {
    if constexpr (i == 1)
       g();
    else if constexpr (i == 2)
       h();
    else
       ??? // <--error
}
Run Code Online (Sandbox Code Playgroud)

有什么我们可以写的东西,???这样f<3>()在编译时调用就会失败?

c++ static-assert constexpr c++20 if-constexpr

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

验证固定长度字符串数组在编译时是否已排序

当尝试验证固定长度字符串数组在编译时是否已排序时,使用 时会出现奇怪的行为strncmp

如果验证函数引用全局数组,则 N 的所有值似乎都有效。

#include <cstring>

#define N 8 // vary values of N

const char STRINGS[][N] = {"a", "b", "c"};

constexpr bool is_sorted_global() {
    for (int i = 0; i < sizeof(STRINGS) / N - 1; i++) {
        if (strncmp(STRINGS[i], STRINGS[i + 1], N) > 0) {
            return false;
        }
    }

    return true;
}

int main()
{
    // always works for any N
    static_assert(is_sorted_global(), "list is not sorted");
}
Run Code Online (Sandbox Code Playgroud)

但是,如果使用函数模板,则只有 N 小于或等于 8 的值才有效。

template<const char …
Run Code Online (Sandbox Code Playgroud)

c++ sorting c-strings static-assert constexpr

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

确定存储在 std::vector 中的对象是否可以轻松复制

此代码无法编译,因为静态断言失败。

#include <vector>
#include <type_traits>

class A {
};

int main()
{
    std::vector<A> v;
    static_assert(std::is_trivially_copyable<decltype(v[0])>::value);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

另一方面,如果我将 替换decltype(v[0])A,则它可以编译。问题在于v[0]是 的类型引用A而不是A. 我怎样才能让它v以某种方式工作?

c++ static-assert

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

仅限具有枚举非类型模板参数的C++模板函数的专门化

这个问题关系到这一个除了不是处理类型名称的模板参数,我想使用一个枚举非类型模板参数.

是否有可能只有特化的模板化(类成员函数),在非类型模板参数的情况下没有通用(工作)定义?

  1. 通过在类体中声明并仅提供特化,我能够使一个版本工作,但是任何使用非定义模板参数的误操作都不会产生错误,直到链接.更糟糕的是,缺失的符号隐含地指的是枚举的整数值而不是它的名称,所以它会让其他开发人员感到困惑.

  2. 我能够BOOST_STATIC_ASSERT从引用的问题中获取技术仅适用于typename模板参数.

此代码演示了这个想法.我不希望CAT-version调用编译:

#include <iostream>
#include <boost/static_assert.hpp>

// CLASS HEADER FILE:
struct foo_class
{
    enum AllowedTypes { DOG, CAT };

    template <AllowedTypes type>
    void add_one_third( double bar ) const
    {
        BOOST_STATIC_ASSERT_MSG(sizeof(type)==0, "enum type not supported.");
    }
};

// CLASS SOURCE FILE
template<>
void foo_class::add_one_third<foo_class::DOG>( double bar ) const
{
    std::cout << "DOG specialization: " << bar + 1./3. << std::endl;
}


// USER SOURCE FILE
int main()
{
    std::cout << "Template Specialization!\n\n"; …
Run Code Online (Sandbox Code Playgroud)

c++ enums static-assert template-specialization

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

专门用于生成编译时错误的模板函数

如果用户尝试使用给定的模板参数调用所述函数,那么如何在编译时专门化模板函数来生成错误?

通过使用以下习语,我能够为模板获得此行为...

template <typename T>
class MyClass< std::vector<T> >;
Run Code Online (Sandbox Code Playgroud)

我试图修改的函数的基本签名是......

template <typename T>
T bar(const int arg) const {
  ...
}
Run Code Online (Sandbox Code Playgroud)

如果我使用与以前禁用某些模板相同的范例......

template<>
std::string foo::bar(const int arg) const;
Run Code Online (Sandbox Code Playgroud)

我可以生成链接器错误,我认为这比运行时错误更令人满意,但仍然不是我正在寻找的.

因为我不能够使用C++ 11,我不能使用static_assert,如所描述这里.相反,我试图这样使用BOOST_STATIC_ASSERT......

template<>
std::string foo::bar(const int arg) const {
  BOOST_STATIC_ASSERT(false);
  return "";
}
Run Code Online (Sandbox Code Playgroud)

但是,这会产生以下编译时错误,即使我没有尝试使用我试图禁止的模板参数调用该函数的实例...

error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>'
Run Code Online (Sandbox Code Playgroud)

我找到了这篇文章,但它并没有真正提供我觉得适用于我的任何见解.有人可以帮忙吗?

c++ templates boost static-assert

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