2013-05-13 50 views
0

下面的代碼是由Yingle Jia's code的另一位程序員修改的,我不得不將它移植到Linux。它編譯於VS2010完全正常,但是當我嘗試建立在Ubuntu用gcc 4.6.3,它在代理模板元編程的問題

template <class R ACF_DELEGATE_COMMA ACF_DELEGATE_TEMPLATE_PARAMS> 
class Delegate<R (ACF_DELEGATE_TEMPLATE_ARGS)> 

顯示錯誤的錯誤消息是:

../../../mySDK-master/include/abc/DelegateTemplate.h:45:1: error: pasting "," and "class" does not give a valid preprocessing token 
../../../mySDK-master/include/abc/DelegateTemplate.h:46:1: error: pasting "," and "T" does not give a valid preprocessing token 
../../../mySDK-master/include/abc/DelegateTemplate.h:74:1: error: pasting "," and "a" does not give a valid preprocessing token 

線45和46是兩個代碼行數DelegateTemplate.h我粘貼在上面。

Delegate.h

// Copyright (C) 2004-2005 Yingle Jia 
// 
// Permission to copy, use, modify, sell and distribute this software is 
// granted provided this copyright notice appears in all copies. 
// This software is provided "as is" without express or implied warranty, 
// and with no claim as to its suitability for any purpose. 
// 
// AcfDelegate.h 
// 

#ifndef __Acf_Delegate__ 
#define __Acf_Delegate__ 

#ifndef __Acf_Corlib__ 
#include <stdexcept> // for std::runtime_error 
#endif // #ifndef __Acf_Corlib__ 
#include <utility> // for std::pair 

// Macros for template metaprogramming 

#define ACF_JOIN(a, b)  ACF_DO_JOIN(a, b) 
#define ACF_DO_JOIN(a, b)  ACF_DO_JOIN2(a, b) 
#define ACF_DO_JOIN2(a, b) a##b 

#define ACF_MAKE_PARAMS1_0(t) 
#define ACF_MAKE_PARAMS1_1(t) t##1 
#define ACF_MAKE_PARAMS1_2(t) t##1, ##t##2 
#define ACF_MAKE_PARAMS1_3(t) t##1, ##t##2, ##t##3 
#define ACF_MAKE_PARAMS1_4(t) t##1, ##t##2, ##t##3, ##t##4 
#define ACF_MAKE_PARAMS1_5(t) t##1, ##t##2, ##t##3, ##t##4, ##t##5 
#define ACF_MAKE_PARAMS1_6(t) t##1, ##t##2, ##t##3, ##t##4, ##t##5, ##t##6 

#define ACF_MAKE_PARAMS2_0(t1, t2) 
#define ACF_MAKE_PARAMS2_1(t1, t2) t1##1 t2##1 
#define ACF_MAKE_PARAMS2_2(t1, t2) t1##1 t2##1, t1##2 t2##2 
#define ACF_MAKE_PARAMS2_3(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3 
#define ACF_MAKE_PARAMS2_4(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4 
#define ACF_MAKE_PARAMS2_5(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5 
#define ACF_MAKE_PARAMS2_6(t1, t2) t1##1 t2##1, t1##2 t2##2, t1##3 t2##3, t1##4 t2##4, t1##5 t2##5, t1##6 t2##6 

#define ACF_MAKE_PARAMS1(n, t)   ACF_JOIN(ACF_MAKE_PARAMS1_, n) (t) 
#define ACF_MAKE_PARAMS2(n, t1, t2) ACF_JOIN(ACF_MAKE_PARAMS2_, n) (t1, t2) 

namespace CORE 
{ 

#ifndef __Acf_Corlib__ 
class InvalidOperationException : public std::runtime_error 
{ 
public: 
    InvalidOperationException() : std::runtime_error("Invalidate operation") 
    { 
    } 
}; 
#endif // #ifndef __Acf_Corlib__ 

template <class TSignature> 
class Delegate; // no body 

} 

// Specializations 

#define ACF_DELEGATE_NUM_ARGS 0 // Delegate<R()> 
#include "DelegateTemplate.h" 
#undef ACF_DELEGATE_NUM_ARGS 

#define ACF_DELEGATE_NUM_ARGS 1 // Delegate<R (T1)> 
#include "DelegateTemplate.h" 
#undef ACF_DELEGATE_NUM_ARGS 

#define ACF_DELEGATE_NUM_ARGS 2 // Delegate<R (T1, T2)> 
#include "DelegateTemplate.h" 
#undef ACF_DELEGATE_NUM_ARGS 

#define ACF_DELEGATE_NUM_ARGS 3 // Delegate<R (T1, T2, T3)> 
#include "DelegateTemplate.h" 
#undef ACF_DELEGATE_NUM_ARGS 

#define ACF_DELEGATE_NUM_ARGS 4 // Delegate<R (T1, T2, T3, T4)> 
#include "DelegateTemplate.h" 
#undef ACF_DELEGATE_NUM_ARGS 

#define ACF_DELEGATE_NUM_ARGS 5 // Delegate<R (T1, T2, T3, T4, T5)> 
#include "DelegateTemplate.h" 
#undef ACF_DELEGATE_NUM_ARGS 

#define ACF_DELEGATE_NUM_ARGS 6 // Delegate<R (T1, T2, T3, T4, T5, T6)> 
#include "DelegateTemplate.h" 
#undef ACF_DELEGATE_NUM_ARGS 

#define N_INVOKE(DELEGATE,PARAMS) { if(DELEGATE) DELEGATE.Invoke PARAMS; } 
#define N_EVENT_HANDLER(a) std::make_pair(this,&a); 

#endif // #ifndef __Acf_Delegate__ 

和DelegateTemplate.h

// Copyright (C) 2004-2005 Yingle Jia 
// 
// Permission to copy, use, modify, sell and distribute this software is 
// granted provided this copyright notice appears in all copies. 
// This software is provided "as is" without express or implied warranty, 
// and with no claim as to its suitability for any purpose. 
// 
// AcfDelegateTemplate.h 
// 
// Note: this header is a header template and must NOT have multiple-inclusion 
// protection. 

#define ACF_DELEGATE_TEMPLATE_PARAMS ACF_MAKE_PARAMS1(ACF_DELEGATE_NUM_ARGS, class T) 
    // class T0, class T1, class T2, ... 
#define ACF_DELEGATE_TEMPLATE_ARGS  ACF_MAKE_PARAMS1(ACF_DELEGATE_NUM_ARGS, T) 
    // T0, T1, T2, ... 
#define ACF_DELEGATE_FUNCTION_PARAMS ACF_MAKE_PARAMS2(ACF_DELEGATE_NUM_ARGS, T, a) 
    // T0 a0, T1 a1, T2 a2, ... 
#define ACF_DELEGATE_FUNCTION_ARGS  ACF_MAKE_PARAMS1(ACF_DELEGATE_NUM_ARGS, a) 
    // a0, a1, a2, ... 

//// Comma if nonzero number of arguments 
#if ACF_DELEGATE_NUM_ARGS == 0 
    #define ACF_DELEGATE_COMMA 
#else 
    #define ACF_DELEGATE_COMMA , 
#endif 

namespace CORE 
{ 

//------------------------------------------------------------------------- 
// class Delegate<R (T1, T2, ..., TN)> 

template <class R ACF_DELEGATE_COMMA ACF_DELEGATE_TEMPLATE_PARAMS> 
class Delegate<R (ACF_DELEGATE_TEMPLATE_ARGS)> 
{ 
// Declarations 
private: 
    class DelegateImplBase 
    { 
    // Fields 
    public: 
     DelegateImplBase* Previous; // singly-linked list 

    // Constructor/Destructor 
    protected: 
     DelegateImplBase() : Previous(NULL) { } 
     DelegateImplBase(const DelegateImplBase& other) : Previous(NULL) { } 
    public: 
     virtual ~DelegateImplBase() { } 

    // Methods 
    public: 
     virtual DelegateImplBase* Clone() const = 0; 
     virtual R Invoke(ACF_DELEGATE_FUNCTION_PARAMS) const = 0; 
    }; 

的一小部分是不是因爲缺乏在GCC模板元編程支持?我檢查了是否會因爲variadic模板,但這應該是在gcc 4.3本身中修復的。如果你能幫助解決這個錯誤,將不勝感激。

+1

這裏沒有可變參數模板,只是預處理器的黑客試圖解決事實,即C++沒有可變參數模板。這種代碼正是它們被引入的原因。 – Yuushi 2013-05-13 05:53:45

+0

刪除「令牌粘貼操作符##」也沒有幫助。 http://stackoverflow.com/a/1206687/453673。也沒有用空格替換它。 – Nav 2013-05-13 06:35:12

+0

考慮安裝一個新的GCC,如4.8;它具有相當不錯的C++ 2011支持。 – 2013-05-13 08:54:30

回答

1

已解決。我經歷了this page並瞭解應該如何使用令牌粘貼操作符:

原來有一些額外的##運算符,其中Visual Studio忽略了,但gcc沒有。 我改變了線路是這些:

#define ACF_MAKE_PARAMS1_0(t) 
#define ACF_MAKE_PARAMS1_1(t) t ## 1 
#define ACF_MAKE_PARAMS1_2(t) t ## 1, t ## 2 
#define ACF_MAKE_PARAMS1_3(t) t ## 1, t ## 2, t ## 3 
#define ACF_MAKE_PARAMS1_4(t) t ## 1, t ## 2, t ## 3, t ## 4 
#define ACF_MAKE_PARAMS1_5(t) t ## 1, t ## 2, t ## 3, t ## 4, t ## 5 
#define ACF_MAKE_PARAMS1_6(t) t ## 1, t ## 2, t ## 3, t ## 4, t ## 5, t ## 6 

該行早前有這樣的事情##t##2這是產生錯誤。我將它改爲t##2,它工作!榮耀哈利路亞! :-)因此,模板元編程結束了我的考驗。