static_cast*>(0)
- 这是否以 int
类型实例化 the_template
?
询问的原因是以下代码,该代码在使用 Clang 和 GCC 4.4.5 链接时会出错,并带有对 check_error(void*, long)
的未定义引用,表明它不实例化模板。然而,MSVC 和 GCC 4.5.1 编译和链接得很好,导致人们相信它确实实例化了模板。但是,如果省略强制转换,MSVC 和 GCC(4.4.5 和 4.5.1)将仅在 check_error
上出错(所需的行为),而 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);
}
static_cast<the_template<int>*>(0)
- does this instantiate the_template
with type int
?
The reason for asking is the following code, which will error at linking time with an undefined reference to check_error<char>(void*, long)
with Clang and GCC 4.4.5, indicating that it does not instantiate the template. MSVC and GCC 4.5.1 however compile and link just fine, leading to the believe that it does instantiate the template. However, if you leave out the cast, MSVC and GCC (both 4.4.5 and 4.5.1) will error on check_error<char>
only (the wanted behaviour), while Clang will error on both calls. Normally I believe Clang when it comes to conforming stuff, but I wonder:
Which compiler is correct and what does the standard say about it?
#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);
}
发布评论
评论(2)
实例化类模板特化的不是强制转换,而是函数调用,因为参数会触发 ADL 。之所以进行实例化,是因为它的完整性可能会影响程序的语义。
已知 clang 不遵循此处的规范,并且我前段时间发送了 PR。请参阅http://llvm.org/bugs/show_bug.cgi?id=9440
It is not the cast that instantiates the class template specialization, but the function call, because the argument triggers ADL . The instantiation is done because the completeness of it may affect the semantics of the program.
That clang does not follow the spec here is known and a PR was sent by me some time ago. See http://llvm.org/bugs/show_bug.cgi?id=9440
n3242 §14.7.1/1
在我看来,
static_cast
需要声明的实例化,而不是定义的实例化(因为您只是处理指针)。n3242 §14.6.5/1
我认为它应该链接,但也许其他人可以比我更好地解释。
n3242 §14.7.1/1
It seems to me that
static_cast
would require the instantiation of the declarations, but not of the definitions (as you are just dealing with pointers).n3242 §14.6.5/1
I think that it should link, but maybe someone else can interpret better than I can.