为什么编译器尝试实例化一个模板,我不实际在任何地方实例化? [英] Why does the compiler try to instantiate a template that I don't actually instantiate anywhere?

查看:151
本文介绍了为什么编译器尝试实例化一个模板,我不实际在任何地方实例化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下更新

以下是我在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆