Compiler instantiates the function in a template class even without invoking it

ⅰ亾dé卋堺 提交于 2019-12-10 11:42:36

问题


I had a wrong perception that template function in a class is instantiated only if it's invoked. See the below simple code:

template<typename T>
struct A
{
  T *p; 
  T& operator * () { return *p; }
};

int main ()
{
  A<int> ai;   // ok
  int i = *ai;  // works fine
  A<void> av;  // compiler complains even "*av" is not called
}

Just while declaring A<void>, compiler errors out as:

error: forming reference to void

I tried to specialize the function for void outside the template as below:

template<>
void A<void>::operator * () {}

But it doesn't help and gives error as:

error: no member function ‘operator*’ declared in ‘A<void>’

Is there any way to fix this with C++03 ?


回答1:


What about

template < typename T >
struct ReferenceOrVoid
{ typedef T& Value; };

template < >
struct ReferenceOrVoid < void >
{ typedef void Value; };

template<typename T>
struct A
{
    T *p; 
    typename ReferenceOrVoid < T > :: Value
    operator * () { return *p; }
};

Of course it depends what you want A to behave in case T is void. You can also specialise the whole A struct for void, of course.




回答2:


The signature of the function will be instantiated, the body of the function will not. T is substituted in the whole class definition, no matter if you're using the function or not. Note that this:

template<typename T>
struct A
{
  T *p; 
  T *operator * () { return p->aklsdjlkasjd(); }
};

int main ()
{
  A<void> av;  
}

Will compile since you're not using operator*.




回答3:


I think it is sufficient if you give the function a different return type for void:

template <typename T>
struct is _void {
    enum { value = false };
};
template <>
struct is_void<> {
    enum { value = true };
};

struct A {
    ...
    typename enable_if<!is_void<T::value>, T&>::type
    operator*() {
        ...
    }
};

Since the signature may still be checked you may need to use a conditional type, e.g., making it void when instantiated with void:

template <bool, typename T1, typename>
struct conditional {
    typedef T1 type;
};
template <typename T1, typename T2>
struct conditional<false, T1, T2> {
    typedef T2 type;
};


来源:https://stackoverflow.com/questions/12762432/compiler-instantiates-the-function-in-a-template-class-even-without-invoking-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!