私人和公共运营商超载

时间:2012-11-01 09:19:12

标签: c++ operator-overloading

我试图实施Horner的方法并面临一个问题:

root@host:~# cat | g++ -x c++ -std=gnu++11 - && ./a.out
#include <iostream>
#include <iomanip>
#include <iterator>
#include <vector>
#include <numeric>
#include <algorithm>
#include <random>
#include <chrono>

#include <cstdlib>

template< typename F >
class horner
{
public :

    typedef std::vector< F > V;

    horner(F const & x_, V const & c_)
        : x(x_)
        , c(c_)
        , y(0.0L)
    { ; }

    operator F const () const
    {
        return std::accumulate(c.rbegin(), c.rend(), *this).y;
    }

private :

    friend horner std::accumulate< typename V::const_reverse_iterator, horner >(typename V::const_reverse_iterator, typename V::const_reverse_iterator, horner);

    void operator = (F const & rhs)
    {
        y = rhs;
    }

    operator F ()
    {
        y *= x;
        return y;
    }

    F const & x;
    V const & c;
    F y;

};

#define N_COEFF_PARABOLA 3

int main()
{
    typedef double F;
    typedef typename horner< F >::V V;

    V c;
    unsigned seed(std::chrono::system_clock::now().time_since_epoch().count());
    std::cout << "seed = 0x"
              << std::uppercase << std::hex << std::setfill('0') << std::setw(sizeof(seed) * 2)
              << seed << std::endl;
    std::mt19937 generator(seed);
    std::generate_n(std::back_inserter(c), N_COEFF_PARABOLA, generator);

    std::cout << "coefficients: ";
    std::copy(c.begin(), c.end(), std::ostream_iterator< F >(std::cout, " "));
    std::cout << ';' << std::endl;

    F const x(generator());
    F const y(horner< F >(x, c));
    std::cout << "y(" << x << ") = " << y << std::endl;

    // naive
    F xx(1.0L);
    F yy(0.0L);
    for (typename V::size_type i(0); i < c.size(); ++i) {
        yy += c[i] * xx;
        xx *= x;
    }
    std::cout << "y'(" << x << ") = " << yy << std::endl;

    return EXIT_SUCCESS;
}
// press ^D

<stdin>: In function ‘int main()’:
<stdin>:39:5: error: ‘horner<F>::operator F() [with F = double]’ is private
<stdin>:71:32: error: within this context
root@host:~#

在我看来,问题不会出现,因为main()只会看到operator F const & () const版本的类型转换运算符。但确实如此。

错误的原因是什么?

1 个答案:

答案 0 :(得分:4)

可见性和可访问性的概念在C ++中是完全正交的。如果方法可见但不可访问,则编译器可能会在重载决策中选择它并产生硬错误,因为它无法使用它。这是有目的地完成的,因此代码在获取或失去访问权限时不会以静默方式更改语义。