Explicit specification of a class member of a class with a different return type

I am trying to port some C ++ code from Windows to Solaris (Unix). You must change the template code. I am using the Solaris CC compiler, g ++ should have the same problem.

I have a certain piece of code that causes some problems. They are simplified as follows:

#include <exception>
#include <cmath>
#include <string>
#include <iostream>

// define the "not implement" error
class tempException: public std::exception
{
public:
    virtual const char* what() const throw()
    {
        return "not been implemented!";
    }
} nondeferr;

// the template class
template <typename T>
class A
{
public:
    template <typename Val>
    Val getValue(T t) { throw nondeferr; }

    template<>
    double getValue(T t) { return exp( 1.5 * t ); } //Specialize the getValue for double type.
};

// test code
int main()
{
    try
    {
        A<int> testA;

        std::cout << testA.getValue<double>(2) << std::endl;
        std::cout << testA.getValue<std::string>(2) << std::endl;
    }
    catch (tempException& e)
    {
        std::cout << e.what() << std::endl;
    }

return 0;
}

To compile this sample code on UNIX, a compilation error occurs because explicit specialization cannot be in the scope of class A.

Here the getValue function is different from the return type, so we cannot modify it using the overload method.

- A T A T Val . , .

, - ? getValue, getDoubleValue... .


, , A :

template <typename T>
class A
{
public:
    // the Get Value we want
    template <typename R>
    R getValue(T t) { return get_value_impl<R>::apply(*this, t); }

    // the general get value struct
    template<typename R, typename = void>
    struct get_value_impl
    {
        static R apply(A a, T t) { throw nondeferr; }
    };

    // partial specialization, which is allowed in std C++
    template <typename S>
    struct get_value_impl<double, S>
    {
        static double apply(A a, T t) { return exp( 1.5 * t ); }
    };
};

- . . Anycorn .

+1
2
// the template class
template <typename T>
class A {
    template<>
    double getValue(T t) { return exp( 1.5 * t ); }
};

.

:

template <typename T>
class A {
    template<class R>
    R getValue(T t) { return get_value_impl<double>::apply(*this, t); }
    template<class R, class = void>
    struct get_value_impl; // specialize this
};
+3

-, . Visual Studio .

+2

Source: https://habr.com/ru/post/1568838/


All Articles