Tra*_*lip 1 static-assert sfinae c++11
我正在尝试使用static_assert来强制失败.如果您尝试以特定方式实例化特定的模板化函数,我想生成编译器错误.我可以使它工作,但它真的很难看.有更简单的方法吗?
这是我的第一次尝试.这根本不起作用.它总是会生成错误,即使没有人尝试使用此功能.
template< class T >
void marshal(std::string name, T *value)
{
static_assert(false, "You cannot marshal a pointer.");
}
Run Code Online (Sandbox Code Playgroud)
这是我的第二次尝试.它确实有效.如果你不打电话,你就不会有错误.如果您这样做,您会得到一条非常易读的错误消息,指向此行并指向试图实例化它的代码.
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.");
}
Run Code Online (Sandbox Code Playgroud)
问题是这段代码充其量是丑陋的.它看起来像一个黑客.我担心下次更改优化级别,升级编译器,打喷嚏等时,编译器会意识到第二种情况与第一种情况相同,它们都会停止工作.
有没有更好的方法来做我想做的事情?
这是一些背景.我想有几个不同版本的marshal(),它们适用于不同的输入类型.我想要一个使用模板作为默认情况的版本.我想要另一个特别禁止除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]);
}
Run Code Online (Sandbox Code Playgroud)
没有办法做到这一点.您可能能够在编译器上运行它,但生成的程序生成错误,无需诊断.
使用=delete.
template< class T >
void marshal(std::string name, T *value) = delete;
Run Code Online (Sandbox Code Playgroud)
依赖矛盾确实不是最好的方法,但有一个更简单的方法:
template <class...>
struct False : std::bool_constant<false> { };
template <class T>
void bang() {
static_assert(False<T>{}, "bang!");
}
Run Code Online (Sandbox Code Playgroud)
为什么这不属于“无有效专业化”的情况?
好吧,因为您实际上可以使用代码的后半部分进行有效的专业化:
template <>
struct False<int> : std::bool_constant<true> { };
int main() {
bang<int>(); // No "bang"!
}
Run Code Online (Sandbox Code Playgroud)
当然,实际上没有人会专门False在实际代码中破坏你的断言,但这是可能的:)
| 归档时间: |
|
| 查看次数: |
509 次 |
| 最近记录: |