在模板参数中,“T”和“const T”有什么区别吗?

40

以下两种语法有什么区别:

template<int N> struct A;         // (1)

template<const int N> struct A;   // (2)

有关何时使用每种语法的一般准则吗?

3个回答

34

不。

§14.1 [temp.param] p5

[...] 在确定其类型时,忽略模板参数的顶层cv限定符。


这只适用于 typename 参数类型吗?(请参见我的答案)。我无法访问标准,而且在我手头的草案中很难找到有用的信息。 - J.N.
2
@J.N.:不,这段引用特别指的是非类型模板参数(无论如何都不能有 const typename :P)。 - Xeo
接受你的回答。为了完整起见,您可能需要更新编码准则。 - iammilind
1
@iammilind:你在谈论哪些编码准则? - Xeo
尽管“const”在任何情况下都没有用,但您的答案只是讨论它们之间的比较。值得一提的是何时使用哪个版本(即始终使用第一个版本)。这取决于您的意愿:)。这只是未来/初学者访问的参考。 - iammilind
顺便提一下,对于C++20标准,这个引用可以在§14.1 [temp.param] p6 中找到。 - user5534993

7
我通过快速搜索标准找到了这个内容:
template<const short cs> class B { };
template<short s> void g(B<s>);
void k2() {
    B<1> b;
    g(b); // OK: cv-qualifiers are ignored on template parameter types
}

这段评论指出它们被忽略了。

我建议在模板参数中不要使用const,因为这是不必要的。请注意,它们也不是“隐含”的 - 它们是常量表达式,与const不同。


注释不是规范性的。 - Lightness Races in Orbit

2
选择使用int可能不是一个好主意,但对于指针而言则有所不同:
class A
{
public:
    int Counter;
};

A a;


template <A* a>
struct Coin
{
    static void DoStuff()
    {
        ++a->Counter; // won't compile if using const A* !!
    }
};

Coin<&a>::DoStuff();
cout << a.Counter << endl;

有趣的是,如果我相信其他人的答案,标准似乎与我的编译器(GCC 4.6.1 / Ubuntu)不一致 :/ - J.N.
没关系,我可能误解了标准。而@Pubby的答案只是表明在匹配模板时被忽略。 - Xeo
13
const A* 不是 A*const 限定版本,而是一个不相关的类型。A* const 才是 A*const 限定版本。 - CB Bailey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接