为什么编译器尝试实例化一个模板,我不实际在任何地方实例化? [英] Why does the compiler try to instantiate a template that I don't actually instantiate anywhere?
问题描述
以下更新。
以下是我在main.cpp中的完整代码:
template< class T>
struct other_traits;
template< class T>
struct some_traits {
typedef decltype(& T :: operator())Fty;
typedef typename other_traits< Fty> :: type type;
};
int main(){
}
g ++编译正好时Visual Studio 2010出现以下错误:
src\main.cpp(9):错误C2146:语法错误:缺少';'在标识符'类型之前
--src\main.cpp (10):参见类模板实例化some_traits< T>
'正在编译
src\main.cpp(9):error C2868 :'some_traits< T> :: type
':使用声明的非法语法;预期限定名
(我喜欢最后一个,总wtf。)
我可以把它作为VC10中的一个错误,还是早期实例化有什么好的理由?或者是 decltype
的错误,使编译器认为 Fty
不是从属名称?
更新:我试图欺骗编译器,认为 Fty
是使用基类继承的依赖名称:
template< class T>
struct other_traits;
template< class R,class C>
struct other_traits< R(C :: *)()> {
typedef R type;
};
template< class Fty>
struct base_traits {
typedef typename other_traits< Fty> :: type type;
};
template< class T>
struct some_traits
:public base_traits< decltype(& T :: operator())>
{};但是编译器仍然尝试在现场实例化/编译一切,抛出这些错误: src\main.cpp(13):错误C2039:'type':不是'other_traits< T>'的成员
with
[
T =
]
src\main.cpp(19):参考类模板实例化'base_traits< Fty& $ b with
[
Fty =
]
src\main.cpp(19):参考类模板实例化'some_traits< T& b src \main.cpp(13):错误C2146:语法错误:缺少';'在标识符'类型'
src \main.cpp(13):错误C4430:缺少类型说明符 - int假定。注意:C ++不支持default-int
src\main.cpp(13):error C2602:'base_traits< Fty> :: type'不是'base_traits< Fty>
with
[
Fty =
]
src\main.cpp(13):参见'base_traits< Fty> :: type'
with
[
Fty =
]
src\main.cpp(13):error C2868:'base_traits< Fty&宣言;预期限定名
与
[
Fty =
]
$ b b
请注意,模板参数为空。任何想法?
解决方案似乎是 Bug (如果没有设置特殊标志如以下所说的)。
以下是 Oracle网站的摘录a> for C ++ templates:
7.2.2 b
$ b ISO C ++标准允许
开发人员编写模板类
,其中所有成员可能不是
legal template
参数。 只要非法的
成员未实例化,
程序仍然形成良好。 ISO
C ++标准库使用这种
技术。但是,
-template = wholeclass 选项实例化所有成员,因此
不能与这样的模板
类一起使用时用
有问题的模板参数。
Updated below.
The following is the entire code I have in my main.cpp:
template<class T>
struct other_traits;
template<class T>
struct some_traits{
typedef decltype(&T::operator()) Fty;
typedef typename other_traits<Fty>::type type;
};
int main(){
}
But I get the following errors with Visual Studio 2010 while g++ compiles just fine:
src\main.cpp(9): error C2146: syntax error : missing ';' before identifier 'type'
--src\main.cpp(10) : see reference to class template instantiation 'some_traits<T>
' being compiled
src\main.cpp(9): error C2868: 'some_traits<T>::type
' : illegal syntax for using-declaration; expected qualified-name
(I like that last one, total wtf.)
Can I take that as a bug in VC10 or is there any good reason for the early instantiation? Or is it a bug with decltype
that makes the compiler think that Fty
is not a dependent name?
Update: I tried to cheat the compiler in thinking that Fty
is a dependent name using a base class to inherit from:
template<class T>
struct other_traits;
template<class R, class C>
struct other_traits<R (C::*)()>{
typedef R type;
};
template<class Fty>
struct base_traits{
typedef typename other_traits<Fty>::type type;
};
template<class T>
struct some_traits
: public base_traits<decltype(&T::operator())>
{};
But the compiler still tries to instantiate / compile everything on the spot, spewing these errors:
src\main.cpp(13): error C2039: 'type' : is not a member of 'other_traits<T>'
with
[
T=
]
src\main.cpp(19) : see reference to class template instantiation 'base_traits<Fty>' being compiled
with
[
Fty=
]
src\main.cpp(19) : see reference to class template instantiation 'some_traits<T>' being compiled
src\main.cpp(13): error C2146: syntax error : missing ';' before identifier 'type'
src\main.cpp(13): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
src\main.cpp(13): error C2602: 'base_traits<Fty>::type' is not a member of a base class of 'base_traits<Fty>'
with
[
Fty=
]
src\main.cpp(13) : see declaration of 'base_traits<Fty>::type'
with
[
Fty=
]
src\main.cpp(13): error C2868: 'base_traits<Fty>::type' : illegal syntax for using-declaration; expected qualified-name
with
[
Fty=
]
Note that the template parameters are empty. Any ideas?
解决方案 It seems to be a Bug (if there is not special flag set as mentioned below).
Following is an excerpt from Oracle website for C++ templates:
7.2.2
The ISO C++ Standard permits
developers to write template classes
for which all members may not be
legal with a given template
argument. As long as the illegal
members are not instantiated, the
program is still well formed. The ISO
C++ Standard Library uses this
technique. However, the
-template=wholeclass option instantiates all members, and hence
cannot be used with such template
classes when instantiated with the
problematic template arguments.
这篇关于为什么编译器尝试实例化一个模板,我不实际在任何地方实例化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!