调用static_assert(false)的正确方法是什么? [英] What's the right way to call static_assert(false)?

查看:104
本文介绍了调用static_assert(false)的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用static_assert强制某些操作失败。如果您尝试以特定的方式实例化特定的模板化函数,我想生成一个编译器错误。我可以使它工作,但这确实很丑。

I’m trying to use static_assert to force something to fail. If you try to instantiate a specific templated function in a specific way I want to generate a complier error. I could make it work, but it was really ugly. Is there an easier way to do this?

这是我的第一次尝试。这根本没有用。即使没有人尝试使用此功能,它始终会产生错误。

This was my first attempt. This did not work at all. It always generates an error, even if no one tries to use this function.

template< class T >
void marshal(std::string name, T  *value)
{
  static_assert(false, "You cannot marshal a pointer.");
}

这是我的第二次尝试。它确实有效。如果您不拨打电话,则不会出错。如果确实调用了此方法,则会收到一条非常可读的错误消息,该消息指向此行并指向试图实例化该行的代码。

Here’s my second attempt. It actually works. If you don’t call this, you get no error. If you do call this, you get a very readable error message that points to this line and points to the code that tried to instantiate it.

template< class T >
void marshal(std::string name, T  *value)
{
  static_assert(std::is_pod<T>::value && !std::is_pod<T>::value, "You cannot marshal a pointer.");
}

问题是这段代码充其量是丑陋的。看起来像骇客。恐怕下次我更改优化级别,升级编译器,打喷嚏等时,编译器将意识到第二种情况与第一种情况相同,并且它们都将停止工作。

The problem is that this code is ugly at best. It looks like a hack. I’m afraid the next time I change the optimization level, upgrade my compiler, sneeze, etc, the compiler will realize that this second case is the same as the first, and they will both stop working.

是否有更好的方法来做我想做的事情?

Is there a better way to do what I’m trying to do?

这里有一些情况。我想拥有适用于不同输入类型的marshal()的几种不同版本。我想要一个使用模板作为默认案例的版本。我想要另外一个专门禁止除char *之外的任何指针。

Here’s some context. I want to have several different versions of marshal() which work for different input types. I want one version that uses a template as the default case. I want another one that specifically disallows any pointers except char *.

void marshal(std::string name, std::string)
{ 
  std::cout<<name<<" is a std::string type."<<std::endl;
}

void marshal(std::string name, char *string)
{
  marshal(name, std::string(string));
}

void marshal(std::string name, char const *string)
{
  marshal(name, std::string(string));
}

template< class T >
void marshal(std::string name, T value)
{
  typedef typename std::enable_if<std::is_pod<T>::value>::type OnlyAllowPOD;
  std::cout<<name<<" is a POD type."<<std::endl;
}

template< class T >
void marshal(std::string name, T  *value)
{
  static_assert(false, "You cannot marshal a pointer.");
}

int main (int argc, char **argv)
{
  marshal("should be pod", argc);
  marshal("should fail to compile", argv);
  marshal("should fail to compile", &argc);
  marshal("should be std::string", argv[0]);
}


推荐答案

没有办法这个。您也许可以使其在编译器上运行,但是生成的程序不需要诊断即可。

There is no way to do this. You might be able to make it work on your compiler, but the resulting program is ill formed no diagnostic required.

使用 = delete

Use =delete.

template< class T >
void marshal(std::string name, T  *value) = delete;

这篇关于调用static_assert(false)的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆