加载中…
个人资料
肖渺◎长沙
肖渺◎长沙
  • 博客等级:
  • 博客积分:0
  • 博客访问:0
  • 关注人气:0
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

zthread库(version 2.3.2)在gcc 3.4.2下编译问题已经解决方法

(2007-04-27 11:38:42)
分类: 技术研讨
 zthread库(version 2.3.2)在gcc 3.4.2下编译问题如下:

提示:

g++ -DHAVE_CONFIG_H -I. -I. -I. -I../include -g -O2 -Wall -DNDEBUG -g -O2 -Wall -DNDEBUG -MT AtomicCount.lo -MD -MP -MF .deps/AtomicCount.Tpo -c AtomicCount.cxx  -fPIC -DPIC -o .libs/AtomicCount.o
In file included from vanilla/SimpleAtomicCount.cxx:26,
                 from AtomicCount.cxx:55:
../include/zthread/Guard.h: In destructor `ZThread::Guard<LockType, LockingPolicy>::~Guard()':
../include/zthread/Guard.h:494: error: there are no arguments to `isDisabled' that depend on a template parameter, so a declaration of `isDisabled' must be available
../include/zthread/Guard.h:494: error: (if you use `-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)

查看zthread/include/guard.h文件内容如下:

/*
* Copyright (c) 2005, Eric Crahen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

#ifndef __ZTGUARD_H__
#define __ZTGUARD_H__

#include "zthread/NonCopyable.h"
#include "zthread/Exceptions.h"

namespace ZThread {

//
// GuardLockingPolicyContract {
//
// createScope(lock_type&) 
// bool createScope(lock_type&, unsigned long) 
// destroyScope(lock_type&) 
//
// }
//

/**
* @class LockHolder
* @author Eric Crahen <http://www.code-foo.com>
* @date <2003-07-16T17:55:42-0400>
* @version 2.2.0
*
* This is a simple base class for Guards class. It allows Guards
* that have compatible targets to refer to each others targets
* allowing for the construction of Guards that share the same lock
* but have different locking policies.
*/
template <class LockType>
class LockHolder {

  LockType &_lock;
  bool _enabled;

public:

  template <class T>
  LockHolder(T& t) : _lock(extract(t)._lock), _enabled(true) { }
 
  LockHolder(LockHolder& holder) : _lock(holder._lock), _enabled(true) { }

  LockHolder(LockType& lock) : _lock(lock), _enabled(true) { }

  void disable() {
    _enabled = false;
  }

  bool isDisabled() {
    return !_enabled;
  }

  LockType& getLock() {
    return _lock;
  }

protected:

  template <class T> 
  static LockHolder& extract(T& t) {
    // Design and Evolution of C++, page 328
    return (LockHolder&)(t);
  }

};

/**
* @class CompoundScope
* @author Eric Crahen <http://www.code-foo.com>
* @date <2003-07-16T17:55:42-0400>
* @version 2.2.0
*
* Locking policy that aggregates two policies that share a target.
* It is not appropriate to use with any type of OverlappedScope
*/
template <class Scope1, class Scope2>
class CompoundScope {
public:

  template <class LockType>
  static void createScope(LockHolder<LockType>& l) {

    Scope1::createScope(l);
    Scope2::createScope(l);

  }

  template <class LockType>
  static void createScope(LockHolder<LockType>& l, unsigned long ms) {

    if(Scope1::createScope(l, ms))
      if(!Scope2::createScope(l, ms)) {

        Scope1::destroyScope(l);
        return false;

      }
      
    return true;

  }

  template <class LockType>
  static void destroyScope(LockHolder<LockType>& l) {

    Scope1::destroyScope(l);
    Scope2::destroyScope(l);

  }

};


/**
* @class LockedScope
* @author Eric Crahen <http://www.code-foo.com>
* @date <2003-07-16T17:55:42-0400>
* @version 2.2.0
*
* Locking policy for Lockable objects. This policy acquire()s a Lockable
* when the protection scope is created, and it release()s a Lockable
* when the scope is destroyed.
*/
class LockedScope {
public:

  /**
   * A new protection scope is being created by l2, using an existing scope
   * created by l1.
   *
   * @param lock1 LockType1& is the LockHolder that holds the desired lock
   * @param lock2 LockType1& is the LockHolder that wants to share
  template <class LockType1, class LockType2>
  static void shareScope(LockHolder<LockType1>& l1, LockHolder<LockType2>& l2) {
   
    l2.getLock().acquire();

  }
   */

  /**
   * A new protection scope is being created.
   *
   * @param lock LockType& is a type of LockHolder.
   */
  template <class LockType>
  static bool createScope(LockHolder<LockType>& l, unsigned long ms) {

    return l.getLock().tryAcquire(ms);

  }

  /**
   * A new protection scope is being created.
   *
   * @param lock LockType& is a type of LockHolder.
   */
  template <class LockType>
  static void createScope(LockHolder<LockType>& l) {

    l.getLock().acquire();

  }

  /**
   * A protection scope is being destroyed.
   *
   * @param lock LockType& is a type of LockHolder.
   */
  template <class LockType>
  static void destroyScope(LockHolder<LockType>& l) {

    l.getLock().release();

  }

};


/**
* @class UnlockedScope
* @author Eric Crahen <http://www.code-foo.com>
* @date <2003-07-16T17:55:42-0400>
* @version 2.2.0
*
* Locking policy for Lockable objects. This policy release()s a Lockable
* when the protection scope is created, and it acquire()s a Lockable
* when the scope is destroyed.
*/
class UnlockedScope {
public:

  /**
   * A new protection scope is being created by l2, using an existing scope
   * created by l1.
   *
   * @param lock1 LockType1& is the LockHolder that holds the desired lock
   * @param lock2 LockType1& is the LockHolder that wants to share
   */
  template <class LockType1, class LockType2>
  static void shareScope(LockHolder<LockType1>& l1, LockHolder<LockType2>& l2) {

    l2.getLock().release();

  }

  /**
   * A new protection scope is being created.
   *
   * @param lock LockType& is a type of LockHolder.
  template <class LockType>
  static void createScope(LockHolder<LockType>& l) {

    l.getLock().release();

  }
   */

  /**
   * A protection scope is being destroyed.
   *
   * @param lock LockType& is a type of LockHolder.
   */
  template <class LockType>
  static void destroyScope(LockHolder<LockType>& l) {

    l.getLock().acquire();

  }

};

 

/**
* @class TimedLockedScope
* @author Eric Crahen <http://www.code-foo.com>
* @date <2003-07-16T17:55:42-0400>
* @version 2.2.0
*
* Locking policy that attempts to enterScope some resource
* in a certain amount of time using an tryEnterScope-relase protocol.
*/
template <int TimeOut>
class TimedLockedScope {
public:

  /**
   * Try to enterScope the given LockHolder.
   *
   * @param lock LockType& is a type of LockHolder.
   */
  template <class LockType1, class LockType2>
  static void shareScope(LockHolder<LockType1>& l1, LockHolder<LockType2>& l2) {

    if(!l2.getLock().tryAcquire(TimeOut))
      throw Timeout_Exception();
      
  }

  template <class LockType>
  static void createScope(LockHolder<LockType>& l) {

    if(!l.getLock().tryAcquire(TimeOut))
      throw Timeout_Exception();

  }

  template <class LockType>
  static void destroyScope(LockHolder<LockType>& l) {

    l.getLock().release();

  }

};


/**
* @class OverlappedScope
* @author Eric Crahen <http://www.code-foo.com>
* @date <2003-07-16T17:55:42-0400>
* @version 2.2.0
*
* Locking policy allows the effective scope of two locks to overlap
* by releasing and disabling one lock before its Guard does so.
*/
class OverlappedScope {
public:

  template <class LockType1, class LockType2>
  static void transferScope(LockHolder<LockType1>& l1, LockHolder<LockType2>& l2) {

    l1.getLock().acquire();

    l2.getLock().release();
    l2.disable();

  }

  template <class LockType>
  static void destroyScope(LockHolder<LockType>& l) {

    l.getLock().release();

  }

};

 

/**
* @class Guard
* @author Eric Crahen <http://www.code-foo.com>
* @date <2003-07-16T17:55:42-0400>
* @version 2.2.0
*
* Scoped locking utility. This template class can be given a Lockable
* synchronization object and can 'Guard' or serialize access to
* that method.

* For instance, consider a case in which a class or program have a 
* Mutex object associated with it. Access can be serialized with a
* Guard as shown below.
*
* @code
*
* Mutex _mtx;
* void guarded() {
*
   Guard<Mutex> g(_mtx);
*
* }
*
* @endcode
*
* The Guard will lock the synchronization object when it is created and
* automatically unlock it when it goes out of scope. This eliminates
* common mistakes like forgetting to unlock your mutex.
*
* An alternative to the above example would be
*
* @code
*
* void guarded() {
*
    (Guard<Mutex>)(_mtx);
*
* }
*
* @endcode
*
* HOWEVER; using a Guard in this method is dangerous. Depending on your
* compiler an anonymous variable like this can go out of scope immediately
* which can result in unexpected behavior. - This is the case with MSVC
* and was the reason for introducing assertions into the Win32_MutexImpl
* to track this problem down
*
*/
template <class LockType, class LockingPolicy = LockedScope>
class Guard : private LockHolder<LockType>, private NonCopyable {

  friend class LockHolder<LockType>;

public:
 
  /**
   * Create a Guard that enforces a the effective protection scope
   * throughout the lifetime of the Guard object or until the protection
   * scope is modified by another Guard.
   *
   * @param lock LockType the lock this Guard will use to enforce its
   * protection scope.
   * @post the protection scope may be ended prematurely
   */
  Guard(LockType& lock) : LockHolder<LockType>(lock) {

    LockingPolicy::createScope(*this);

  };

  /**
   * Create a Guard that enforces a the effective protection scope
   * throughout the lifetime of the Guard object or until the protection
   * scope is modified by another Guard.
   *
   * @param lock LockType the lock this Guard will use to enforce its
   * protection scope.
   * @post the protection scope may be ended prematurely
   */
  Guard(LockType& lock, unsigned long timeout) : LockHolder<LockType>(lock) {

    if(!LockingPolicy::createScope(*this, timeout))
      throw Timeout_Exception();

  };

  /**
   * Create a Guard that shares the effective protection scope
   * from the given Guard to this Guard.
   *
   * @param g Guard<U, V> guard that is currently enabled
   * @param lock LockType the lock this Guard will use to enforce its
   * protection scope.
   */
  template <class U, class V>
  Guard(Guard<U, V>& g) : LockHolder<LockType>(g) {

    LockingPolicy::shareScope(*this, extract(g));
   
  }

  /**
   * Create a Guard that shares the effective protection scope
   * from the given Guard to this Guard.
   *
   * @param g Guard guard that is currently enabled
   * @param lock LockType the lock this Guard will use to enforce its
   * protection scope.
   */
  Guard(Guard& g) : LockHolder<LockType>(g) {

    LockingPolicy::shareScope(*this, g);
   
  }


  /**
   * Create a Guard that transfers the effective protection scope
   * from the given Guard to this Guard.
   *
   * @param g Guard<U, V> guard that is currently enabled
   * @param lock LockType the lock this Guard will use to enforce its
   * protection scope.
   */
  template <class U, class V>
  Guard(Guard<U, V>& g, LockType& lock) : LockHolder<LockType>(lock) {

    LockingPolicy::transferScope(*this, extract(g));

  }


  /**
   * Create a Guard that transfers the effective protection scope
   * from the given Guard to this Guard.
   *
   * @param g Guard guard that is currently enabled
   * @param lock LockType the lock this Guard will use to enforce its
   * protection scope.
   */
  Guard(Guard& g, LockType& lock) : LockHolder<LockType>(lock) {

    LockingPolicy::transferScope(*this, g);

  }
 

  /**
   * Unlock a given Lockable object with the destruction of this Guard
   */
  ~Guard() throw();

}; /* Guard */


template <class LockType, class LockingPolicy>
Guard<LockType, LockingPolicy>::~Guard() throw() {
   
  try {
   
    if(!isDisabled())
      LockingPolicy::destroyScope(*this);
   
  } catch (...) { /* ignore */ } 
 
}


};

#endif // __ZTGUARD_H__

分析:模板类Guard<LockType, LockingPolicy> 私有继承于 private LockHolder<LockType>, private NonCopyable;
而模板类LockHolder<LockType>中提供了isDisabled()方法啊,为什么编译器不识别呢?(GNU gcc/g++版本的问题?)


 __________________________________

So closed,no matter how far,could be much more from the heart...


--------------------------------------------------------------------------------
 
这个是编译器编译器版本的问题.印象里Zthread的作者已经停止开发一段时间了.

g++3.4以后版本的名字查找方法和以前的版本不同,问题这里有解释.http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html.

实际上解决方法编译结果已经说了.

一种是使用-fpermissive开关来允许老的语法,
用export CXXFLAGS=-fpermissive,然后在configure

另一种方法可以在调用函数时加this.
this->isDisabled()

还可以把isDisabled()在那个类头部分重新声明一下.
using BaseClass<T>::isDisabled(); 


简单而言,对应g++3.4以后版本的名字查找方法,模板类中对基类方法或者基类的成员变量的调用,如果该基类方法或者基类成员变量与模板参数类型(typename T)无关,则需要使用this-> 调用或者在类定义中声明using BaseClass<T>::function();

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有