3

我尝试实现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类型转换运算符的版本。但它是。

错误的原因是什么?

4

1 回答 1

4

The concepts of visibility and accessibility are completely orthogonal in C++. If a method is visible, but not accessible, the compiler may select it in overload resolution and produce a hard error because it can't use it. This is done on purpose so code does not change semantics silently when it gains or looses access.

于 2012-11-01T10:07:44.810 回答