使用msvc-2010编译模板时遇到问题。它使用gcc 4.6.3完美地工作。
我已经将代码归结为必要的代码(当然没有意义):
//Variant that works
template <typename T, T* Ptr>
void callFun()
{
}
//Traits class (type expands to the same type T* as above)
template <typename T>
class TraitsClass
{
public:
typedef T* type;
};
//Essentially the same as callFun2, only that the
//type of Ptr is expressed indirectly over a traits class
//The usage of this class is not possible, because of the error described below
template <typename T, typename TraitsClass<T>::type Ptr>
void callFun2()
{
}
//Provides a compile constant ptr for this example
void testFun()
{
}
int main()
{
//Works
callFun<void(), &testFun>();
//Fails
callFun2<void(), &testFun>();
//Works
callFun2<void(), 0>();
return 0;
}
错误:
error C2975: 'Ptr' : invalid template argument for 'callFun2', expected compile-time constant expression
我觉得有趣的是,只有当通过Traits类中的typedef使用第二个类型参数时它才会失败。 g ++正确编译此示例而没有警告,即使使用-Wall -Wextra -Werror -pedantic(当然,除了未使用的参数)
非常感谢。
答案 0 :(得分:2)
嗯,我认为答案是编译器不是由神写的。编译器行业的编程标准非常高,MS C ++是一个很好的编译器,但它仍然包含bug。我遇到了以下内容,这与您指出的内容类似:
template <class item_struct>
struct THeapBasedArray
{
void Sort(int (__cdecl *compareFunction)(const item_struct *item1,
const item_struct *item2));
};
struct Item { int x; };
struct ItemPtrsArray : public THeapBasedArray<Item*>
{
static int __cdecl Compare1(const Item **pp1, const Item **pp2);
typedef Item *ItemPtr;
static int __cdecl Compare2(const ItemPtr *pp1, const ItemPtr *pp2);
};
int main()
{
ItemPtrsArray vect;
vect.Sort(ItemPtrsArray::Compare1);
vect.Sort(ItemPtrsArray::Compare2);
}
对Sort的第一次调用失败了:
cpptest1.cxx(21):错误C2664:'THeapBasedArray :: Sort':无法将参数1从'int(_ cdecl *)(const Item **,const Item **)'转换为'int ( _cdecl *)(const item_struct *,const item_struct *)
而第二次调用编译器很好。对我来说,这是编译器中的一个错误。有时这会发生。我想这就是答案。