标签: static-assert

虚拟地从一个类派生的力量

我们在项目中有一个特殊的接口框架,部分要求是代表接口的类只能用作虚拟基类,而不能用作非虚拟基类.有没有办法在代码中强制执行此操作?也就是说,如果类是从非虚拟派生的,则产生编译错误.

我可以访问由VS 2010实现的C++ 11:这意味着static_assert,enable_if并且<type_traits>可用.

c++ static-assert virtual-inheritance type-traits c++11

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

MSVC12认为从std :: array派生的聚合不是pod

鉴于以下内容

#include <array>

struct litmus final : std::array<unsigned char, 16>
{
};

static_assert(std::is_pod<std::array<unsigned char, 16> >::value, "not pod");

// this fails on MSVC:
static_assert(std::is_pod<litmus>::value, "not pod");
Run Code Online (Sandbox Code Playgroud)

以下编译器同意litmuspod:

但是,MSVC12(VS2013 RTM)认为第二个断言失败.

  1. 谁是对的?
  2. 是否有任何技巧可以让MSVC将该类视为pod?

编辑有关信息:is_trivially_copyable<litmus>在MSVC上返回true-ness.对于许多不严格要求实际POD的情况,这可能很有用.

c++ static-assert pod visual-c++

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

为什么一个表达式不变,而另一个表达式不变?

为什么Visual Studio 2013编译器拒绝第一个静态断言(错误C2057),而不是第二个?

#include <limits>

typedef int Frequency;

const Frequency minHz{ 0 };
const Frequency maxHz{ std::numeric_limits<Frequency>::max() };
const Frequency invalidHz{ -1 };
static_assert(minHz < maxHz, "minHz must be less than maxHz");                // C2057
static_assert(invalidHz < minHz || invalidHz > maxHz, "invalidHz is valid");  // OK
Run Code Online (Sandbox Code Playgroud)

c++ static-assert c++11 visual-studio-2013

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

如何static_assert std :: array成员的大小

我想明确关于成员变量的数组大小限制,以阻止其他人意外地进行愚蠢的更改.以下天真的尝试将无法编译:

struct Foo
{
    std::array< int, 1024 > some_array;
    static_assert( (some_array.size() % 256) == 0, "Size must be multiple of 256" );
    //^ (clang) error: invalid use of non-static data member 'some_array'
};
Run Code Online (Sandbox Code Playgroud)

即使std::array::sizeconstexpr,我也不能直接使用static_assert,因为函数和我的成员变量都不是静态的.

我想出的解决方案是使用decltype(因为我不想键入数组),如下所示:

static_assert( (decltype(some_array)().size() % 256) == 0, "Size must be multiple of 256" );
Run Code Online (Sandbox Code Playgroud)

这看起来像是默认构造一个右值,我认为它不是一个constexpr.

为什么这样做?

有没有更简洁的方法来实现静态断言?

c++ clang static-assert c++11 stdarray

8
推荐指数
2
解决办法
3387
查看次数

static_assert和Intel C++编译器

阅读cppreference.com:

静态断言声明可能出现在块作用域(作为块声明)和类体内(作为成员声明)

好的,现在我有以下代码:

struct foo_t
{
    static constexpr std::size_t maxAlignment()
    {
        // This is just a sample; I removed real code from this method.
        return std::max(alignof(__m128), __alignof(__m256));
    }

    static_assert(0 == ((maxAlignment() -1) & maxAlignment()), "some message");
};
Run Code Online (Sandbox Code Playgroud)

MSVC 2015和Intel C++ 16.0.2都没有编译此代码(前者显示"错误C2131:表达式未评估为常量",后者显示"函数调用必须在常量表达式中具有常量值"错误并指向调用maxAlignmentin static_assert).

但MSVC 2015 Update 1 确实编译了以下代码,而英特尔C++ 16.0.2 则没有:

template <typename T, std::size_t Alignment>
struct foo_t
{
    static constexpr std::size_t maxAlignment()
    {
        return std::max(std::alignment_of<T>::value, Alignment);
    }

    static_assert(0 == ((maxAlignment() -1) & …
Run Code Online (Sandbox Code Playgroud)

c++ static-assert icc visual-c++

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

一种安全,符合标准的方法,只有在实例化了static_assert的情况下,才能使类模板专业化而无法编译?

假设我们要创建一个只能用数字实例化的模板类,否则就不应该编译。我的尝试:

#include <type_traits>

template<typename T, typename = void>
struct OnlyNumbers{
public:
    struct C{};
    static_assert(std::is_same<C,T>::value, "T is not arithmetic type.");

    //OnlyNumbers<C>* ptr;
};

template<typename T>
struct OnlyNumbers<T, std::enable_if_t<std::is_arithmetic_v<T>>>{};

struct Foo{};
int main()
{
    OnlyNumbers<int>{}; //Compiles
    //OnlyNumbers<Foo>{}; //Error
}
Run Code Online (Sandbox Code Playgroud)

现场演示 -所有三个主要的编译器似乎都能按预期工作。我知道已经有一个类似的问题,答案引用了该标准。接受的答案使用temp.res.8temp.dep.1来回答该问题。我认为我的问题有所不同,因为我只是在问我的示例,我不确定标准对此的看法。

我认为我的程序不是格式错误的,并且仅当编译器尝试实例化基本模板时,它才应该无法编译。我的推理:

  • [temp.dep.1]:

    在模板内部,某些构造的语义可能因一个实例而异。这样的构造取决于模板参数。

    这应该使std::is_same<C,T>::value依赖T

  • [temp.res.8.1]:

    如果模板中的语句或模板未实例化,则无法为模板或constexpr的子语句生成有效的专业化名称;或者

    不适用,因为存在有效的专业化,尤其OnlyNumbers<C>是有效的,并且可以在类内部用于例如定义成员指针variable(ptr)。实际上,通过删除断言并取消注释ptrOnlyNumbers<Foo>代码行得以编译。

  • [temp.res.8.2-8.4]不适用。

  • [temp.res.8.5]我也不认为这适用,但是我不能说我完全理解本节。

我的问题是:我的推理正确吗?这是一种使特定[class] *模板static_assert仅在实例化时无法编译的安全,符合标准的方法吗?

*基本上,我对类模板感兴趣,请随时包含函数模板。但是我认为规则是相同的。

**这意味着没有TT=C从内部使用那样可以从外部实例化模板。即使C可以通过某种方式访问​​,我也不认为有一种方法可以引用它,因为它会导致这种递归OnlyNumbers<OnlyNumbers<...>::C> …

c++ templates static-assert language-lawyer

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

确保派生类实现静态方法

我想确保派生类实现一个特定的静态方法.我认为这样做应该可以使用static_assert,std :: is_same,decltype,CRTP并且可能使用SFINAE.但是,到目前为止,我发现的类似代码非常复杂,似乎我还没有完全理解它使我无法将其用于我的需求.

到目前为止我尝试过的是这个

template <class T>
class Base 
{
    static_assert(std::is_same<decltype(T::foo(1)), int>::value, "ERROR STRING");
};

class Derived : public Base <Derived>
{
public:
    static int foo(int i) { return 42; };
};
Run Code Online (Sandbox Code Playgroud)

但是,它没有编译告诉我,即使方法正确实现,Derived也没有名为foo的元素.此外,在static_assert内的表达式中为foo提供实际参数会感觉不对.

搜索SO揭示了一个类似的问题,最终引导我到这段代码,检查一个类型有方法begin()和end()返回迭代器.所以我试着采用这个代码来满足我的需求.

template <class T>
class Base 
{
    template<typename C>
    static char(&g(typename std::enable_if<std::is_same<decltype(static_cast<int(C::*)(int)>(&C::foo)), int(C::*)(int)>::value, void>::type*))[1];

    template<typename C>
    static char(&g(...))[2];

    static_assert(sizeof(g<T>(0)) == 1, "ERROR STRING");
};
Run Code Online (Sandbox Code Playgroud)

但是这段代码没有编译,因为断言触发了.

所以我的问题是

  1. 为什么编译器在我的第一个例子中找不到Derived :: foo?
  2. typename C::const_iterator(C::*)() const示例代码到底意味着什么?是不是一个const函数返回C …

c++ static-assert crtp type-traits c++11

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

是否可以使用 GTest 进行 ASSERT_DOES_NOT_COMPILE?

假设一个模板类,我们在编译时断言整数模板参数必须大于零:

template<int N>
class A
{
public:

    A() {
        static_assert(N > 0, "N needs to be greater 0.");
    }

};
Run Code Online (Sandbox Code Playgroud)

是否可以创建一个可编译在运行时报告错误的 googletest 单元测试?例如:

TEST(TestA, ConstructionNotAllowedWithZero)
{
    ASSERT_DOES_NOT_COMPILE( 
        {
            A< 0 > a;
        }
    );
}
Run Code Online (Sandbox Code Playgroud)

c++ static-assert googletest

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

用户定义的文字字符串:编译时长度检查

我有一个用户定义的文字运算符,它只对特定长度的字符串有意义,如下所示:

constexpr uint16_t operator "" _int(const char* s, std::size_t len)
{
    return len == 2 ? s[0] | (s[1] << 8) : throw;
}
Run Code Online (Sandbox Code Playgroud)

这有效:

"AB"_int // equals 16961
Run Code Online (Sandbox Code Playgroud)

但这也可以编译,我不希望它:

"ABC"_int // throws at runtime
Run Code Online (Sandbox Code Playgroud)

我试过了static_assert(len == 2),但在 constexpr 函数中是不允许的。

如何"ABC"_int在编译时导致错误?

c++ static-assert compile-time-constant user-defined-literals c++11

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

if constexpr 内部使用 static_assert 格式良好吗?

我昨天读了几个关于在an 子句中使用的答案。我知道根据标准,它被认为是格式错误的(即使某些编译器,包括 MSVC2017,会接受它)。Qt 也会将此标记为错误。static_assert(false, "Some message")elseif constexpr

我的问题是,下面的代码是否符合标准?(我倾向于这么认为,但我想确认一下。)

template <typename TypeOfValue>
static void PushValue(duk_context* ctx, TypeOfValue value) {
    // Push value onto duktape stack
    if constexpr (std::is_same<TypeOfValue, int>::value) {
        // Push int
        duk_push_int(ctx, value);
    } else if constexpr (std::is_same<TypeOfValue, uint32_t>::value) {
        // Push uint
        duk_push_uint(ctx, value);
    } else {
        // Unsupported type
        static_assert(bool_value<false, TypeOfValue>(), "Unsupported type");
    }    
}

template <bool value, typename T>
static constexpr bool bool_value() {return value;}        
Run Code Online (Sandbox Code Playgroud)

编辑: …

c++ static-assert language-lawyer constexpr if-constexpr

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