简体   繁体   English

C++ 模板参数和部分特化:强类型还是弱类型?

[英]C++ template parameter and partial specialization : strong or weak typing?

Today, a friend of mine and I struggled a lot on a stupid mistake, and I make me wondered about how template parameters work in C++.今天,我和我的一个朋友在一个愚蠢的错误上挣扎了很多,我让我想知道模板参数在 C++ 中是如何工作的。 Consider the following code, where I try to partially specialize a class attr<MyClass<I>> where I is an unsigned int , though MyClass expects an int parameter :考虑以下代码,我尝试部分特化一个类attr<MyClass<I>> ,其中I是一个unsigned int ,尽管MyClass需要一个int参数:

#include <iostream>

template<int I>
class MyClass
{

};

template<typename T>
struct attr;

template<unsigned int I>
struct attr<MyClass<I>>
{

};

int main(int argc, char *argv[])
{
    attr<MyClass<1>> att;
    return 0;
}

g++ fails with error message g++失败并显示错误消息

main.cpp: In function ‘int main(int, char**)’:
main.cpp:20:22: erreur : aggregate ‘attr<MyClass<1> > att’ has incomplete type and cannot be defined
     attr<MyClass<1>> att;

And clang compiles it (only a warning due to the fact that att is unused).然后clang编译它(由于att未使用,因此只是一个警告)。

So I was wondering :所以我想知道:

  • is there anything in the spec that would rule in favor of one or the other ?规范中是否有任何内容会支持其中一个?

  • could we say that clang template parameter's typing is weaker than g++ 's ?我们可以说clang模板参数的类型比g++的弱吗?

Yes, GCC is correct to reject, at least according to current Standards.是的,至少根据现行标准,GCC 拒绝是正确的。 Perhaps Clang folks implement some defect report here, I wouldn't know.也许 Clang 人在这里实现了一些缺陷报告,我不知道。

http://eel.is/c++draft/temp.deduct.type#17 http://eel.is/c++draft/temp.deduct.type#17

If P has a form that contains <i> , and if the type of the corresponding value of A differs from the type of i, deduction fails.如果 P 的形式包含<i> ,并且 A 的对应值的类型与 i 的类型不同,则推导失败。 If P has a form that contains [i] , and if the type of i is not an integral type, deduction fails.如果 P 的形式包含[i] ,并且 i 的类型不是整数类型,则推导失败。

Their testcase in their testsuite tests this only for for functions, for which they appear to emit sensible error messages: https://github.com/llvm-mirror/clang/blob/master/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp .他们在测试套件中的测试用例仅针对函数进行测试,对于这些函数,它们似乎会发出合理的错误消息: https : //github.com/llvm-mirror/clang/blob/master/test/CXX/temp/temp.fct。规格/temp.deduct/temp.deduct.type/p17.cpp

Also, since the partial specialization can never be deduced, we also run intohttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#549 , which asks whether such constructs should possibly be rejected up-front.此外,由于永远无法推导出部分专业化,我们还会遇到http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#549 ,询问是否应该拒绝此类构造前期。 In my opinion, http://eel.is/c++draft/temp.res#8 could be applied if you wanted:在我看来,如果您愿意,可以应用http://eel.is/c++draft/temp.res#8

"Knowing which names are type names allows the syntax of every template to be checked. The program is ill-formed, no diagnostic required, if: “知道哪些名称是类型名称可以检查每个模板的语法。程序格式错误,无需诊断,如果:

  • no valid specialization can be generated for a template and that template is not instantiated, or ..."无法为模板生成有效的专业化并且该模板未实例化,或者......”

There is no legal way to trigger an instantiation of that template, hence you could argue that no valid specialization can be generated for it.没有合法的方法来触发该模板的实例化,因此您可能会争辩说无法为其生成有效的特化。 Under that interpretation, behavior is undefined and anything is legal to do.在这种解释下,行为是未定义的,任何事情都是合法的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM