如何验证某些模板 *not* 为给定的参数类型编译?
Posted
技术标签:
【中文标题】如何验证某些模板 *not* 为给定的参数类型编译?【英文标题】:How to validate that some template does *not* compile for given argument types? 【发布时间】:2009-05-12 22:22:43 【问题描述】:我正在编写一个智能 ptr 模板,该模板仅针对给定的基类及其子类进行实例化,它提供了类似于 boost::shared_ptr 的隐式转换到模板 MyPtr<U>
的变体 MyPtr<T>
很长因为从 T* 到 U* 的转换是有效的(有效的基类和 const 兼容)。
这在 vs2005 中运行良好,但不适用于 g++ 在 linux 上,所以我的同事在那里更改了它,但这样做破坏了 const 正确性。
我的问题是我想对某些转换无效(例如将MyPtr<const T>
分配给MyPtr<T>
)进行单元测试,导致文件无法编译!但是您不能在解决方案中没有未编译的文件...
如果有一些特定于 VS 的 #pragma 或一些可以测试给定构造的 SFINAE 技巧NOT有效,因此无法编译?
谢谢,--DD
【问题讨论】:
你能发布一些损坏的代码吗? 你可以查看我问过的关于单元测试编译时错误的这个问题:***.com/questions/605915/unit-test-compile-time-error 感谢卢克的链接。这确实与我的问题具有相同的精神。但答案也让我想要更好的东西。我有一种感觉,如果不打算编译的代码被包装在模板中,那么 SFINAE 可能会有所帮助,该模板稍后用于函数重载解决方案。在此代码中允许不为一个重载候选者编译,而是选择默认情况重载,并且在运行时可检测到。当我有时间时,我会尝试这些方面的东西。 【参考方案1】:您可以运行命令行编译器cl
,它很容易设置,并捕获其错误消息输出。
没有生成文件,也几乎没有来自解决方案/项目的任何信息。只是包含路径和源文件。最简单的是,您只需要一个“反转”另一个程序的退出代码的程序:
#include <sstream>
#include <stdlib.h>
int main(int argc, char *argv[])
std::ostringstream command;
for (int n = 1; n < argc; n++)
command << argv[n] << " ";
return (system(command.str().c_str()) == EXIT_SUCCESS)
? EXIT_FAILURE : EXIT_SUCCESS;
它只是简单地将传递给它的参数重组为(省略其自己的名称)并退出生成的命令行,然后如果失败则返回成功,如果成功则返回失败。这足以欺骗 Visual Studio 或 make
。
从技术上讲,重新构建的命令行应该引用参数,但只有当你足够疯狂地在构建目录或源文件名中放置空格时才需要!
【讨论】:
我正在寻找在visual studio中运行的东西,这与解决方案中的人民币我的单元测试项目没有什么不同,选择“设置为启动项目”并按F5。拥有可以复制解决方案中所有构建信息的外部脚本/makefile 并不是我真正想到的那种解决方案,并且在发生故障时的报告也可能是外部的。 您似乎在想象这将比实际上更难!请参阅更新的答案。真的很简单(比写一个智能指针简单多了)。 我宁愿写智能 ptr 代码(好吧,实际上我宁愿使用 Boost 的,但这是一个特例,它实际上使用了一个 shared_ptr 内部)宁愿尝试写一个跨平台编译器分叉、输出解析、可与 VS 和 GCC/make 一起使用的程序 ;-) 这太过分了。输出只是退出代码。据我所知,这是一个完全微不足道的问题。我已经用必要的代码更新了答案。【参考方案2】:如果给定的参数(在您的情况下为“const T”)将满足所有其他单元测试,除了您正在寻找的这个,这不是表明它是一个完全可以接受的情况吗? 换句话说,如果它有效,为什么要禁止它?
【讨论】:
呃。不 ;-) 如果你有一个 boost::shared_ptr以上是关于如何验证某些模板 *not* 为给定的参数类型编译?的主要内容,如果未能解决你的问题,请参考以下文章