Why is this dependent type not considered a specialization using a template argument?

I am trying to combine specializations so as not to write them several times. For example, in the code below, I try to specialize "float" and "double" as one implementation case for foo :: func (); Then I use a different implementation for "bool".

template<typename T> struct foo;

template<typename T> struct bar;
template<> struct bar<float> { typedef float Type; };
template<> struct bar<double> { typedef double Type; };

/* specialize for float and double here */
template<typename T> struct foo<typename bar<T>::Type> {
    static void func() { ... }
};

template<> struct foo<bool> {
    static void func() { ... }
};

These are errors in GCC 4.4.3. (This is the target compiler, because it presents for Ubuntu Server 10.04 LTS, which supposedly has three more years to live.) Error:

foo.cpp:8: error: template parameters not used in partial specialization:
foo.cpp:8: error:         β€˜T’

The error refers to the first specialization of foo (for "float" and "double.")

, ++ - - , . , - ( ), !

+5
2
template<typename T> struct foo<typename bar<T>::Type> {
    static void func() { ... }
};

T , T, bar<T>::Type.

, ,

foo<double> foodouble;

, , , bar, double, foo? , , bar, double , - :

template<> struct bar<int> { typedef double Type; };

bar<double>::Type bar<int>::Type double. , : bar, double , bar.


SFINAE :

#include <iostream>

template<typename T> struct bar { typedef void type; };
template<> struct bar<float> { typedef bar<float> type; };
template<> struct bar<double> { typedef bar<double> type; };

template<typename T> 
struct foo : bar<T>::type
{
    static void func() 
    { 
        std::cout << "primary template for float and double" << std::endl; 
    }
};

template<> 
struct foo<bool> 
{
    static void func() 
    { 
       std::cout << "specialization for for bool" << std::endl; 
    }
};

int main()
{
     foo<float>::func();
     foo<double>::func();
     foo<bool>::func();
}

(-):

primary template for float and double
primary template for float and double
specialization for for bool

, struct foo : bar<T>::type . . , , , , float, double bool; , foo<int>. , undefined, , .

+6

, , , . . , ++ - 14.8.2.5. :

The non-deduced contexts are:
β€” The nested-name-specifier of a type that was specified using a qualified-id.
β€” A non-type template argument or an array bound in which a subexpression references a template
parameter.
β€” A template parameter used in the parameter type of a function parameter that has a default argument
that is being used in the call for which argument deduction is being done.
β€” A function parameter for which argument deduction cannot be done because the associated function
argument is a function, or a set of overloaded functions (13.4), and one or more of the following apply:
β€” more than one function matches the function parameter type (resulting in an ambiguous deduc-
tion), or
β€” no function matches the function parameter type, or
β€” the set of functions supplied as an argument contains one or more function templates.
β€” A function parameter for which the associated argument is an initializer list (8.5.4) but the parameter
does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list
type. [ Example:
template<class T> void g(T);
g({1,2,3});
// error: no argument deduced for T
β€” end example ]
β€” A function parameter pack that does not occur at the end of the parameter-declaration-clause.

id, .

, non-type bool foo - - :

template<typename T, bool is_decimal = false>
struct foo {...}; // general case

template<typename T>
struct foo<T, true> { ... }; // case where T is float or double

...

+2

All Articles