当我们在C ++中使用像Template这样的变量时,它意味着什么?

时间:2015-04-24 19:18:34

标签: c++

我正在读一本C ++书。我遇到了类似于以下内容的代码:

int foo=3;
if(foo<1>(3))
    cout<<"hello world!"<<endl;

那么,int foo如何被用作模板?这是什么意思?

我相信:这是C ++的一个巨大含糊之处,因为如果我们有这样的模板代码,会发生什么? C ++如何处理歧义

template <int N>
  void foo( const int t )
  {
     // ....
  }

1 个答案:

答案 0 :(得分:10)

这绝对是奇怪的代码,所以如果这本书没有解释,请刻录书并要求退款。摘要是:它不是模板。它不是比较,而是比比较。

if(foo<1>(3))

相同
if( (foo<1) >3)

几乎完全相同
bool first = (foo < 1);  //false since `foo` is 3
bool second = (first > 3); //false evaluates to zero, so this is false as well
if (second) //this is never entered
    cout<<"hello world!"<<endl; //compiler probably doesn't even generate this.


至于关于模板歧义的问题,语言清楚地指明默认值是什么,尽管它通常不是你想要的。我编译了您的示例,发现它发出了这样的结果:warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses] http://coliru.stacked-crooked.com/a/49479996464507dc。所以我们知道它仍然被解释为运算符而忽略了这种情况下的模板。

但是,有很多地方C ++在这些方面“含糊不清”。最常见的是“最令人烦恼的解析”。

struct A {};
struct B {
    B(A a) {}
};
int main() {
    B obj(A());

您希望使用默认构造的B创建名为obj的{​​{1}},但它会声明一个名为A的函数,该函数返回obj 1}}它的参数是本身一个不带任何东西并返回B的函数。然后,当您尝试将其用作变量时,会出现各种奇怪且令人困惑的错误:http://coliru.stacked-crooked.com/a/c6fd627be8529b26

这是一个更阴险的版本:

A

template <class T> struct A { static int v; }; template<> struct A<int> using v = float; }; template<class T> struct B { B() { A<T>::v; } }; 内,很难判断B是一个类型还是一个变量。这个很糟糕,以至于C ++必须添加一个特殊的关键字v,以便程序员可以告诉编译器它实际上是一个类型,因为编译器总是认为它是一个变量。