0

下面的代码是由另一个程序员改编自家应乐的代码,我不得不把它移植到 Linux 上。它在 VS2010 中编译得非常好,但是当我尝试使用 gcc 4.6.3 在 Ubuntu 中构建时,它显示错误

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

DelegateTemplate.h第 45 和 46 行是我在上面粘贴的两行代码。

代表.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 中缺少模板元编程支持吗?我检查了它是否是因为可变参数模板,但这应该在 gcc 4.3 本身中修复。如果您能帮助解决此错误,将不胜感激。

4

1 回答 1

1

解决了。我浏览了这个页面并了解了应该如何使用令牌粘贴运算符:

结果发现有一些额外的##运算符被 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并且有效!荣耀哈利路亚!:-) 这样就结束了我对模板元编程的考验。

于 2013-05-13T07:48:10.447 回答