为什么此依赖类型不计为使用模板参数的专用化
Why does this dependent type not count as specialization using the template argument?
我试图将专业分组在一起,以避免多次编写它们。例如,在下面的代码中,我尝试将"float"和"double"专门化为foo::func()的一个实现案例;然后,我使用另一个实现"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() { ... }
};
这在 GCC 4.4.3 中会出现错误。(这是一个目标编译器,因为它是Ubuntu Server 10.04 LTS的库存,据称还有三年的寿命。错误是:
foo.cpp:8: error: template parameters not used in partial specialization:
foo.cpp:8: error: ‘T’
该错误是指foo的第一个特化(用于"float"和"double"。
我看不出我在这里违反了C++的哪一部分——如果有人知道这一章和经文,我将不胜感激。此外,如果有人知道实现相同目标的另一种方法(为某些类型组重用专用化,而无需不必要的冗长代码),我也将不胜感激任何建议!
template<typename T> struct foo<typename bar<T>::Type> {
static void func() { ... }
};
您在不可推导的上下文中使用T
,因此编译器即使知道bar<T>::Type
的值也无法推断T
。
假设你写,
foo<double> foodouble;
那么你可能会想,bar
在实例化foo
时会选择哪个专门针对double
?只有当编译器可以确保不存在另一种将double
定义为嵌套类型的bar
专用化时,这才似乎是合理的,如下所示:
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>
。但是,我还注意到您未定义主模板,因此我希望此解决方案符合您的要求。
我认为你正在尝试的是不可能的。 我在这里发现了一个类似的问题。 我没有链接,但 c++ 标准的相关部分是 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 指定类型,因此无法推断参数。
不用多想,作为一个快速的解决方法,你可以向foo添加第二个非类型bool参数 - 类似于:
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
祝你好运...
- 具有常量引用参数的函数模板专用化
- 通过依赖类型使用非类型模板参数的单类型模板参数类模板的部分专用化
- 具有多个参数的模板化类专用化,其中一个模板参数是模板本身
- 具有可变参数非类型参数的模板专用化
- 类专用化,没有用作专用化模板参数的类的模板参数
- 基于枚举参数调用专用模板方法
- 检查类是否具有模板专用化(使用布尔值或 int 等模板参数)
- 专用于可变参数模板成员函数
- 如何将模板类专用化为也接受模板模板参数
- 调用模板专用化,具有更多参数的单参数模板调用的特定值
- 有没有办法根据 lambda 参数返回类型部分专用化我的模板化函数?
- C++ 将派生类的成员函数指针作为参数传递时选择了错误的模板专用化
- cpp 模板专用化,错误说参数 1 的类型为 T,这取决于参数 T
- 具有不同非类型模板参数的模板类部分专用化
- 带有void类型和参数的C++11模板专用化
- 如何进行模板化类型化参数专用化?
- C++具有可变参数专用参数的模板,用于参数数量
- 使用类型参数专用化部分模板参数(VC++ v140 工具集)
- 模板模板可变参数专用化
- 将可变模板模板参数专用于最小数量的参数:合法或不合法