C++1y/C++14:变量模板专用化
C++1y/C++14: Variable Template Specialization?
根据 C++1y/C++14 N3690,变量模板专用化的类型是否必须与主模板的类型相同?
template<int x>
char y = f(x);
template<>
double y<42> = g();
如果是这样,是否有可能以某种方式未定义主要内容?
template<int x>
???? y = ???; // undefined
template<>
double y<42> = g();
草案中涉及哪些内容?
类模板的等效功能为:
template<int x>
struct S
{
static char y;
};
template<>
struct S<42>
{
static double y;
};
和
template<int x>
struct S; // undefined
template<>
struct S<42>
{
static double y;
};
变量模板专用化的类型是否必须与主模板的类型相同?
否,变量模板的显式(或部分(专用化可以指定与隐式实例化所隐含的类型不同的类型。在为 Clang 实现该功能时,我们发现规范没有规则要求在这种情况下匹配类型,我们将问题提交给C++核心工作组,在那里确认此遗漏是故意的。
是否可以以某种方式不定义主要内容?
如果不指定类型,就不可能声明主变量模板 - 没有语法允许这样的事情。
草案中涉及哪些内容?
这两者都被省略了 - 没有规则要求类型匹配,也没有语法来声明没有类型的变量模板。所以我不能指出标准的任何特定部分并说"这是规则不的地方"。
如果您有权访问C++标准委员会的反射器,请参阅以 core-23901 开头的线程以对此进行讨论。
了 clang 主干-std=c++1y
:
#include <iostream>
template<int x>
char y = 3;
template<>
double y<42> = 2.5;
char c {y<17>};
double d {y<42>};
因此,要么变量模板的专用化不需要与其主模板具有相同的类型,要么 clang 有一个错误的 N3690 实现
我完全希望专业化的声明需要与主模板完全匹配,包括其类型。对于变量模板来说,这并不是什么新鲜事。我还没有追查标准中的细节,看看它在哪里指定了这个细节。
下面的代码似乎做了一些类似于你想要的事情,即让变量类型保持打开状态:
#include <iostream>
template <int X> struct var_type { typedef int type; };
template <> struct var_type<42> { typedef double type; };
int f(int x) { return x; }
double g() { return 3.14; }
template <int X>
typename var_type<X>::type var = f(X);
template <>
typename var_type<42>::type var<42> = g();
int main()
{
std::cout << "var<17>=" << var<17> << 'n';
std::cout << "var<42>=" << var<42> << 'n';
}
如果是这样,是否有可能以某种方式未定义主要内容?
我认为这有效地做到了:
template<class T> std::enable_if_t<sizeof(T*)==0> var;
template<> auto var<float > = 1;
template<> auto var<double> = 2;
例如,var<char>
似乎是一个无效的变量。
对于非类型模板参数(NTTA(情况,我想这更棘手,因为您需要考虑所有不可实例化的情况
template<int x> std::enable_if_t<x!=42 and x!=43> var;
template<> auto var<42> = 1;
template<> auto var<43> = 2;
在这种情况下,var<41>
是不可思议的。
我不确定这有多强大。它适用于 clang 和 gcc:https://godbolt.org/z/hxcnjMrce
最后,可能更具可读性:
template<class T> auto var = std::enable_if_t<sizeof(T*)==0>{};
template<int x> auto var2 = std::enable_if_t<x!=42 and x!=43>{};
<小时 />编辑:实际上NTTA更容易,唯一的挑战是使布尔表达式依赖于参数x
。
template<int x> auto var2 = std::enable_if_t<x!=x>{};
template<> auto var2<42> = 1;
template<> auto var2<43> = 2;
<小时 />这是受到另一个技巧的启发:https://devblogs.microsoft.com/oldnewthing/20200311-00/?p=103553
推断 Clang 表达的是用于标准化的功能有点冒险。(注意:这个答案我没有参考任何东西。
当然,允许更改类型的后果是,在以任何方式引用模板后,您无法对其进行专用化,而对于所有其他类型的模板,截止时间是使用 ODR。除非他们计划一些古怪的事情,否则这看起来像一个Clang错误。
始终可以使用类型模板来声明变量模板的类型。
template< typename t >
struct x_type { typedef … type; };
template< typename t >
typename x_type< t >::type x = …;
现在x_type
可能是专业化的。这只是防止了Clang目前有缺陷的可能性。它不允许引用不确定类型的对象。C++只是不支持这一点。引用对象 ODR-使用类模板专用化。
- 成员变量如何使用专用类模板?
- 变量模板的部分专用化
- 模板变量的显式专用化
- 如何从具有专用化的类模板定义静态成员变量?
- 变量模板专用化
- 如果参数具有成员变量,则专用化函数
- 变量模板的显式专用化
- C++类模板专用变量
- 指针和 c 样式数组变量的专用模板
- 禁用成员函数和变量,而不使用继承或类专用化
- gcc中变量模板的错误显式模板专用化
- 类模板专用化中的成员变量别名
- 具有 std::enable_if 的多变量模板专用化
- C++ 使类的成员变量成为子类中的专用化
- c++ 如何初始化部分模板专用化的静态变量
- 如果实例化,如何使模板化变量专用化在编译时失败
- 如何在同一成员变量中存储不同的专用模板类
- 访问专用模板的私有/继承成员变量
- C++1y/C++14:变量模板专用化
- 模板成员变量专用化