我有一个非常简单的功能使用static_assert.麻烦的是我想要static_assert在函数声明中涉及的行为 - 特别是推断返回类型.似乎没有任何地方可以插入,static_assert以便我可以在编译器无法推断出返回类型之前触发它.
到目前为止,我将返回类型推导和静态断言放在结构中.这将触发断言,这很好,但它仍然会在类型推导上产生错误,这是我想要消除的噪音.
#include <type_traits>
#include <functional>
#include <memory>
#include <map>
#include <iostream>
#include <string>
#include <cstdio>
#include <tuple>
#include <sstream>
#include <vector>
#include <algorithm>
template<typename T, typename X> struct is_addable {
template<typename Test, typename Test2> static char test(decltype(*static_cast<Test*>(nullptr) + *static_cast<Test2*>(nullptr))*);
template<typename Test, typename Test2> static int test(...);
static const bool value = std::is_same<char, decltype(test<T, X>(nullptr))>::value;
};
template<typename T, typename X> struct is_addable_fail {
static const bool value = is_addable<T, X>::value; …Run Code Online (Sandbox Code Playgroud) templates static-assert generic-programming visual-studio-2010 c++11
我们有复杂的模板类,其中有一些方法不适用于某些策略或类型.因此,当我们检测到这些类型时(在编译时,使用类型特征),我们使用一条好消息来激活一个静态断言.
现在我们也进行了大量的手动模板实例化.部分原因是这些方法被迫编译器对语法进行语法检查.它还减少了库用户的编译时间.问题是静态断言总是被触发,因此我们无法手动实例化有问题的模板类.
这有解决方法吗?
编辑:为了使它更清楚,这是一个例子(在这种情况下显式实例化将在someFunc1()上失败:
// header
template <typename T>
class someClass
{
void someFunc() {}
void someFunc1() { static_assert(false, assertion_failed); }
};
// source
template someClass<int>; // Explicit instantiation
Run Code Online (Sandbox Code Playgroud)
EDIT2:这是另一个例子.这次你可以编译它看看我的意思.首先立即编译.代码应该编译.然后取消注释[2]并且静态断言应该触发.现在注释掉[2]和取消注释[1].静态断言将触发,因为您明确地实例化模板.我想避免删除显式实例化,因为它带来的好处(参见上面的好处).
namespace Loki
{
template<int> struct CompileTimeError;
template<> struct CompileTimeError<true> {};
}
#define LOKI_STATIC_CHECK(expr, msg) \
{ Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
template <typename T>
class foo
{
public:
void func() {}
void func1() { LOKI_STATIC_CHECK(sizeof(T) == 4, Assertion_error); }
};
template …Run Code Online (Sandbox Code Playgroud) 我注意到在实例化时不会触发类模板中的静态断言typedef.
#include <type_traits>
template <typename T>
struct test_assert
{
static_assert( std::is_same< T, int >::value, "should fail" );
};
typedef test_assert< float > t;
Run Code Online (Sandbox Code Playgroud)
此代码编译没有错误.如果我尝试创建一个实例,那么断言就会失败:
t obj; // error: static assertion failed: "should fail"
Run Code Online (Sandbox Code Playgroud)
最后,如果我用条件替换条件false,即使我没有实例化类模板,断言也会失败:
template <typename T>
struct test_assert
{
static_assert( false, "always fails" );
};
Run Code Online (Sandbox Code Playgroud)
我在gcc-4.5.1和gcc-4.7.0上尝试了这段代码.这种行为是否正常?编译器什么时候应该验证静态断言?我想涉及两阶段查找,但是typedef不应该触发第二阶段吗?
C++ 11中是否有任何新的,很酷的功能允许我们在编译时检测现在标记为已弃用的API是否实际上被某人调用?
从我读到的关于新static_assert功能的内容来看,它似乎不够灵活,不能用于那种分析.
但是还有什么我们可以使用的吗?
可选地,是否有任何提升允许这种编译时检查?
我有一些类型,每个类型具有相同名称的子类型:
struct TypeA {
typedef int subtype;
};
struct TypeB {
typedef float subtype;
};
Run Code Online (Sandbox Code Playgroud)
以及没有此子类型但在相同上下文中使用的类型:
struct TypeC {
// (no subtype defined)
};
Run Code Online (Sandbox Code Playgroud)
如何添加一个虚拟子类型,它提供自定义编译错误消息?
我(迄今为止不成功)的尝试是:
struct TypeC {
struct subtype {
static_assert(false, "Attempt to access the non-existent subtype of TypeC.");
};
};
Run Code Online (Sandbox Code Playgroud)
但是static_assert(false, ...)无法工作,因为即使从不访问类型,编译器也会抛出错误.
如何将评估延迟static_assert到访问类型的时间?
失败的尝试是引入一个虚拟枚举并从中构造一个表达式:
enum { X };
static_assert(X != X, "...");
Run Code Online (Sandbox Code Playgroud)
具体使用情况:我有一个类模板List,其与子类型定义head和tail如果非空,并且应该给一个错误,如果使用这些子类型,如果它是空的:
template<typename...>
struct List;
// empty list:
template<>
struct List<> {
struct head { static_assert(false, …Run Code Online (Sandbox Code Playgroud) 我想要的类型double,float,complex<double>并complex<float>通过一个static_assert条件.我认为static_assert(std::is_floating<T>::value, "some message")可以做到这一点,但是复杂的类型没有通过这个测试(至少在gcc-4.10下).
我将添加什么谓词以确保long double允许这四种类型(也许也可以是s)作为模板实例化,但没有别的?
我正在尝试编译以下代码,clang++ -std=c++11 -c它失败了:
void g() noexcept {}
template <typename Func>
void f(Func && func) noexcept(noexcept(func()))
{ static_assert(noexcept(func()), "func()"); } // No error!
void h() { f(&g); } // No error!
static_assert(noexcept(f(&g)), "Error!");
Run Code Online (Sandbox Code Playgroud)
Clang 3.4.2给出的错误信息是:
test.h:9:1: error: static_assert failed "Error!"
static_assert(noexcept(f(&g)), "Error!");
^ ~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么?
当尝试static_assert使用参数来评估逗号运算符时,编译失败
void fvoid() {}
int main() {
int a = (1, 2); // a=2
int b = (fvoid(), 3); // b=3
int d = ( , 5);
// ^
// error: expected primary-expression before ',' token. OK
int c = (static_assert(true), 4);
// ^~~~~~~~~~~~~
// error: expected primary-expression before 'static_assert'. Why?
}
Run Code Online (Sandbox Code Playgroud)
在编译之后,它看起来static_assert()甚至无法解决void.我没有在标准中找到任何关于此的内容.有没有办法使用它与逗号运算符或使用它与其他表达式(没有分号)?
我想编写一个模板函数,只能使用2个数字(例如3和5),如果你尝试将它与其他数字一起使用,则会给出错误.
我可以这样做:
template<int x>
void f();
template<>
void f<3>()
{
cout << "f<3>()\n";
}
template<>
void f<5>()
{
cout << "f<5>()\n";
}
Run Code Online (Sandbox Code Playgroud)
然后我可以正常方式调用此函数:
f<3>();
f<5>();
Run Code Online (Sandbox Code Playgroud)
它编译得很好,如果我尝试错误地使用我的函数:
f<10>();
Run Code Online (Sandbox Code Playgroud)
编译器给我一个错误.
我有这个方法的2个问题:
1.-这是标准吗?我可以使用整数专门设计模板吗?
2.-我不喜欢你使用这种方法时得到的错误,因为错误并没有告诉用户他做错了什么.我更喜欢这样写:
template<int x>
void f()
{
static_assert(false, "You are trying to use f with the wrong numbers");
}
Run Code Online (Sandbox Code Playgroud)
但这不编译.看来我的编译器(gcc 5.4.0)试图首先实例化主模板,因此它给出了(static_assert的)错误.
谢谢您的帮助.
如果您想知道我为什么要这样做是因为我正在学习如何编程微控制器.在微控制器中,你有一些只做一些事情的引脚.例如,引脚3和5是可以生成方波的引脚.如果在一个应用程序中我想生成一个方波,我想写下这样的东西:
square_wave<3>(frecuency);
Run Code Online (Sandbox Code Playgroud)
但是,如果几个月后我想在另一个使用不同微控制器的应用程序中重用这个代码(或更改它),我希望我的编译器对我说:"呃,在这个微控制器中你不能在引脚3中产生方波而5.使用引脚7和9".我认为这可以为我节省很多麻烦(或许不是,我真的不知道.我只是学习如何编程微控制器).
c++ microcontroller templates static-assert template-specialization
有一个非模板化的类,它有一个模板化的构造函数.是否可以在这样的构造函数中初始化成员变量之前检查静态断言?
例如,以下代码T::value()在检查T具有此类方法之前执行.
class MyClass
{
public:
template<typename T>
MyClass(const T &t)
: m_value(t.value())
{
static_assert(HasValueMethod<T>::value, "T must have a value() method");
}
private:
int m_value;
};
Run Code Online (Sandbox Code Playgroud)
放置static_assert在构造函数的正文中工作正常,除非在成员初始化列表的所有错误消息之后打印"T必须有一个value()方法",例如:
prog.cpp: In instantiation of ‘MyClass::MyClass(const T&) [with T = int]’:
prog.cpp:24:16: required from here
prog.cpp:12:21: error: request for member ‘value’ in ‘t’, which is of non-class type ‘const int’
: m_value(t.value())
~~^~~~~
prog.cpp:14:9: error: static assertion failed: T must have a value() method
static_assert(HasValueMethod<T>::value, "T must have …Run Code Online (Sandbox Code Playgroud)