【发布时间】:2012-01-12 19:41:58
【问题描述】:
static_cast<the_template<int>*>(0) - 这是否将 the_template 实例化为 int 类型?
询问的原因是下面的代码,它会在使用 Clang 和 GCC 4.4.5 与 check_error<char>(void*, long) 的未定义引用链接时出错,表明它没有实例化模板。 MSVC 和GCC 4.5.1 但是编译和链接都很好,导致人们相信它确实 实例化了模板。但是,如果您省略演员表,MSVC 和 GCC(4.4.5 和 4.5.1)只会在 check_error<char> 上出错(想要的行为),而 Clang 会在两个调用上出错。通常我相信 Clang 会符合要求,但我想知道:
哪个编译器是正确的,标准是怎么说的?
#include <type_traits>
template<class T>
void check_error(void*, long);
template<class T>
struct foo{
template<class U>
friend typename std::enable_if<
std::is_same<T,U>::value
>::type check_error(foo<T>*, int){}
};
template struct foo<int>;
int main()
{
check_error<int>(static_cast<foo<int>*>(0), 0);
check_error<char>(static_cast<foo<char>*>(0), 0);
}
【问题讨论】:
-
@Matteo:自己写
enable_if和is_same并不难,这是我在 Comeau 测试时所做的,但后来我注意到与 R.Martinho 所做的相同 - Comeau Online 确实如此不链接。 :( -
这看起来像个糟糕的设计。只是远离语言的黑暗角落。你的问题少,别人的问题也少。 :-)
-
我敢打赌,从一个指针到另一个指针的
static_cast要求底层类型是完整的。如果类型不相关,则强制转换必须失败,如果是,则强制转换必须执行必要的多态转换。 -
@Alf:但是我喜欢编译/链接时错误而不是运行时错误,这对于我正在编写的应用程序实际上是有意义的(我知道,他们都这么说)。 :(
-
@KerrekSB 我没有看到任何地方明确说明,但我认为类型必须完整才能确定是否应该可以确定
static_cast的结果。我不清楚是否真的必须实例化模板。
标签: c++ templates c++11 language-lawyer