0

我已经为此苦苦挣扎了大约半天,似乎至少 XCode 4.6 有一个错误,其中模板类的某些声明会违反语言并允许将 const 数据从类内传递到外部函数,参数被定义为没有常量修饰符。

下面的示例将编译,即使 Tcaller::call() 方法的严格模板声明指定作为引用传递的 const 参数,但静态 cmp 函数提供无用的 *const & 修饰符。

template< typename T> struct Tcalled
{
    // !!!error - this prototype doesn't protect the data passed to function
    // because it should be declared with const modifiers but it wouldn't compile then.
    // SEE: Below my NOTE for correct function prototype.
        static bool cmp(const Tcalled*& item, const int& key) //<- correct but doesn't work
        static bool cmp(Tcalled* const & item, const int& key) //<- invalid but works!!
        {
            return (item->index = key); /// error - we modify const object here !
        }

    T index;
};

template < typename T> struct Tcaller
{
    Tcaller(){}

    template < typename K, bool (*compare)(const T& item, const K& key) >
    bool call(int k) const { return compare(data, k); }

    T       data;

};


int main(int argc, char *argv[])
{
    const Tcaller<Tcalled<int>* > tmp;  // <- const data
    int k = 1;

    tmp.call<int,Tcalled<int>::cmp>(k);  //call here WILL modify const data !!

}

问题是:我如何强制 XCode 遵守规则并允许我为我的静态函数创建原型,因为它是为模板参数声明的?至于现在,这些是我在正确声明静态方法时得到的 XCode 错误:

没有匹配的成员函数调用“调用”候选模板被忽略:模板参数“比较”的显式指定参数无效

谢谢!

4

1 回答 1

2

大概你的意思是当参数被声明为Tcalled<T>* const & item并且 bodycmp应该使用==not时它可以工作=

您对模板参数的实例化方式存在误解。这不仅仅是模板参数的复制粘贴替换。您期望用asconst T&实例化时将等效于; 也就是说,“对指向 const 的指针的引用。TTcalled<int>*const Tcalled<int>*&Tcalled<int>

但是,这是错误的,const适用于整个T类型。所以真的,在实例化之后,const T&就相当于Tcalled<int>* const&. 这就是为什么将参数声明为Tcalled* const & item可以正常工作的原因。

为了使它与 as 声明一起工作,const Tcalled<T>*& item必须改变一些事情:

  1. call函数模板参数应该这样定义:

    template < int (*compare)(T& item) >
    

    也就是说,函数指针类型采用 a T&,而不是 a const T&。这是有道理的,因为cmp函数根本不引用const对象(它引用非const指针)。

  2. call功能不应该是const

    int call() { return compare(data); }
    

    这是因为它将其成员传递T给比较,这是对非const对象的引用(指针本身不是const)。如果它是一个const函数,它就不能这样做,因为它不能保证compare不会修改对象。

  3. Tcaller必须用Tas实例化const Tcalled<int>*

    Tcaller<const Tcalled<int>* > tmp;
    
于 2013-04-20T21:53:03.273 回答