【问题标题】:C++ template for all pointers and template for all arrays所有指针的 C++ 模板和所有数组的模板
【发布时间】:2015-03-06 20:39:53
【问题描述】:

我正在寻找以下问题的解决方案:我有一个类,我想为所有类型的指针和所有类型的数组重载一个运算符(在此示例中为 &)。在数组的实现中,我需要访问arraysize,在指针的实现中,我必须能够对取消引用的对象做一些事情。

正如here 指出的那样,数组的方式非常明确:

template<typename T, unsigned int N>
void operator&(T (&arr)[N])
{
    cout << "general array operator: " << N << "\r\n";
}

但是对于指针,以下都不起作用:

// if I use this, the operator gets ambigous for arrays
template<typename T>
inline void operator&(T* p)
{
    cout << "general pointer operator: " << (*p) << "\r\n";
}
// this doesn't work because one cannot dereference void* 
void operator&(void* p)
{
    cout << "general pointer operator\r\n";
    (*this) & (*p);
}

是否有任何好的和干净的解决方案来实现任意数组和任意指针的运算符的不同行为?

这是一个完整的示例代码:

#include <iostream>

struct Class
{
    template<typename T>
    void operator&(T* p)
    {
        std::cout << "general pointer operator" << (*p) << std::endl;
    }

    template<typename T, unsigned int N>
    void operator&(T (&arr)[N])
    {
        std::cout << "general array operator" << N << std::endl;
    }
};

int main()
{
    int myarr[5];
    int* p = myarr;
    Class obj;

    obj & myarr; // error: operator is ambigous
    obj & p; // works

    return 0;
}

【问题讨论】:

  • 我不明白您如何重载 operator&amp; 以返回 void。在我看来,&amp; 应该返回某种类型的指针,(或者可能是 bool?)
  • @abelenky 这是二元 operator&amp;bit-and 运算符,而不是一元 addressof 运算符。它可以返回任何你喜欢的东西。
  • stackoverflow.com/q/28243371/3093378 了解您有歧义的原因

标签: c++ templates pointers


【解决方案1】:

我不得不承认我不知道为什么你的 sn-p 无法正确编译。无论如何,一个好的旧标签调度解决方法似乎正在工作。

class cClass
{

public:
    template<class T, size_t N>
    void impl(T (&x)[N], std::true_type)
    {
        cout << "general array operator" << N << '\n';
    }

    template<typename T>
    void impl(T* p, std::false_type)
    {
        cout << "general pointer operator" << (*p) << '\n';
    }

    template<typename T>
    void operator&(T && x)
    {
        impl( std::forward<T>(x), std::is_array< typename std::remove_reference<T>::type >() );
    }

};

【讨论】:

    【解决方案2】:

    修改代码最少的解决方案是:

    template<typename T>
    void operator&(T*const& p)
    

    消除了歧义。我会自己调度标签。

    【讨论】:

    • 此解决方案是否有任何缺点,或者您为什么要使用标签调度?这个解决方案似乎没有那么复杂......
    • @cwde 主要的缺点是如果你被 C++11 之前的编译器卡住了。标签调度需要 C++11 或 boost。
    • @cwde 标签调度使覆盖显式。这依赖于标准的怪癖来使衰减指针无法在模板级别与T* const&amp; 匹配。我将衰减规则与模板匹配规则混合在一起,虽然它有效,但我既不保证标准同意,也不相信标准中的无害更改将来不会破坏此代码。
    【解决方案3】:

    C++98 的解决方案是让指针获取运算符将 const 引用 指向一个指针。

    #include <iostream>
    
    struct Class
    {
       template<typename T>
       void operator&(T* const &p)
       {
          std::cout << "general pointer operator " << (*p) << std::endl;
       }
    
       template<typename T, unsigned int N>
       void operator&(T (&)[N])
       {
          std::cout << "general array operator " << N << std::endl;
       }
    };
    
    int main()
    {
       int myarr[1] = { 2 };
       int* p = myarr;
       Class obj;
    
       obj & myarr;
       obj & p;
    
       return 0;
    }
    

    输出:

    general array operator 1
    general pointer operator 2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      • 1970-01-01
      • 2019-10-20
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      相关资源
      最近更新 更多