C++ C++;1y/C++;14:变量模板专门化?
根据C++1y/C++14 N3690,变量模板专用化的类型是否必须与主模板的类型相同C++ C++;1y/C++;14:变量模板专门化?,c++,templates,c++14,C++,Templates,C++14,根据C++1y/C++14 N3690,变量模板专用化的类型是否必须与主模板的类型相同 template<int x> char y = f(x); template<> double y<42> = g(); 模板 chary=f(x); 模板 双y=g(); 如果是这样的话,是否有可能以某种方式不定义主元素 template<int x> ???? y = ???; // undefined template<> doubl
template<int x>
char y = f(x);
template<>
double y<42> = g();
模板
chary=f(x);
模板
双y=g();
如果是这样的话,是否有可能以某种方式不定义主元素
template<int x>
???? y = ???; // undefined
template<>
double y<42> = g();
模板
???? y=???;//未定义
模板
双y=g();
草案中涉及到了哪些方面
类模板的等效功能为:
template<int x>
struct S
{
static char y;
};
template<>
struct S<42>
{
static double y;
};
模板
结构
{
静态字符;
};
模板
结构
{
静态双y;
};
及
模板
结构S;//未定义
模板
结构
{
静态双y;
};
我完全希望专门化的声明需要与主模板完全匹配,包括其类型。这对于变量模板来说并不是什么新鲜事。我还没有追查标准中的细节,看看它在哪里指定了这个细节
下面的代码似乎做了一些类似于您想要做的事情,即,将变量类型保持为打开状态:
#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';
}
#包括
模板结构var_type{typedef int type;};
模板结构var_type{typedef double type;};
int f(int x){return x;}
双g(){return 3.14;}
模板
typename var_type::type var=f(X);
模板
typename var_type::type var=g();
int main()
{
std::cout以下代码是用铿锵的主干编译的-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>};
#包括
模板
chary=3;
模板
双y=2.5;
字符c{y};
双d{y};
因此,要么变量模板的专门化不需要与它的主模板具有相同的类型,要么clang的N3690实现有缺陷,那么推断clang表达的是用于标准化的特性就有点冒险了。(注:我没有提到任何关于这个答案的信息。)
当然,允许更改类型的后果是,在模板以任何方式被引用后,您都无法对其进行专门化,而对于所有其他类型的模板,截止时间都是在ODR使用时。除非他们计划一些古怪的事情,否则这看起来像一个叮当作响的bug
始终可以使用类型模板来声明变量模板的类型
template< typename t >
struct x_type { typedef … type; };
template< typename t >
typename x_type< t >::type x = …;
模板
结构x_type{typedef…type;};
模板
typename x_type::type x=…;
现在>代码> xyType 可以是专门的。这只是防止Clang目前是BGGY的可能性。它不允许你引用一个不确定类型的对象。C++不支持这个。引用对象ODR使用类模板特化。< /P> < P> <强>类型的变量模板特化。必须与主模板的类型相同?
否,明确的(或部分的)变量模板的专门化可以指定与隐式实例化所暗示的类型不同的类型。当为Clang实现该特性时,我们发现规范没有规则要求在这种情况下匹配类型,并且我们将问题提交给C++核心工作组,在那里确认了这一遗漏是故意的
是否可以以某种方式保留主字段未定义?
如果不指定类型,就不可能声明主变量模板——没有语法允许这样做
草案中在哪里涉及到这一点?
这两个方面都被省略了——没有规则要求类型匹配,也没有语法来声明没有类型的变量模板。因此,我不能指出标准的任何特定部分并说“这里没有规则”
如果您有权访问C++标准委员会的反射器,请参见以CARE-24901开头的线程来讨论这个问题。
如果是这样的话,是否有可能以某种方式不定义主元素
template<int x>
???? y = ???; // undefined
template<>
double y<42> = g();
我认为这有效地做到了:
template<class T> std::enable_if_t<sizeof(T*)==0> var;
template<> auto var<float > = 1;
template<> auto var<double> = 2;
这是从另一个技巧中得到启发的:你给出的例子与你的开场白不矛盾吗?var
的类型是int,而var
的类型是double。?因此专门化的类型与主模板不匹配。顺便问一下,你知道gcc或clang是否有我们可以使用的变量模板的实现y with?@AndrewTomazos:上述代码使用最新版本编译:在上一次委员会会议上,Chandler Carruth和Richard Smith表示,当使用-std=C++1y
时,clang编译器的功能与当前的C++14草稿完全相同,但大小的交易除外(但这一警告在周五晚上已经存在,可能也会得到纠正)。当实例化包含的类类型时,静态数据成员的声明被隐式实例化,因此我认为变量模板专门化的情况与类模板/静态数据成员的情况是相同的-就显式专门化位置的要求而言,w.r.t.引用。@AndrewTomazos类成员的类型不能通过显式专门化来更改。请参见14.7.1/2-3。这都是“定义必须存在”的术语,也称为ODR用法。decltype
从未实例化其参数,但这种宗族用法无法协调decltype(x)
以及随后的显式专门化。我指的是类模板的显式专门化(包含成员的不同声明类型),而不是类数据成员定义的显式专门化(如下面的示例所示)请注意,数据成员不是模板。正确的映射是类模板S
和变量模板y
@AndrewTomazos之间的映射,我现在看到了。您建议类似于类型的类模板在不同于类似于初始值设定项的默认值模板的时间实例化/使用,但是我们俩
template<int x> std::enable_if_t<x!=42 and x!=43> var;
template<> auto var<42> = 1;
template<> auto var<43> = 2;
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>{};
template<int x> auto var2 = std::enable_if_t<x!=x>{};
template<> auto var2<42> = 1;
template<> auto var2<43> = 2;