函数定义中的decltype中的依赖类型或参数在没有decltype

时间:2017-05-31 21:11:34

标签: c++ c++11 templates language-lawyer

我在定义中使用推断出的返回类型来解析与声明相同的类型。这有效:

template <typename>
struct Cls {
  static std::size_t f();
};

template <typename T>
decltype(sizeof(int)) Cls<T>::f()  { return 0; }

但是,如果我将sizeof(int)替换为sizeof(T) it fails

,则将定义更改为应该相同的内容
template <typename T>
decltype(sizeof(T)) Cls<T>::f() { return 0; }

gcc的错误(clang几乎相同):

error: prototype for ‘decltype (sizeof (T)) Cls<T>::f()’ does not match any in class ‘Cls<T>’
 decltype(sizeof(T)) Cls<T>::f() { return 0; }
                     ^~~~~~
so.cpp:4:24: error: candidate is: static std::size_t Cls<T>::f()
     static std::size_t f();
                        ^

功能参数类型出现同样的问题:

template <typename>
struct Cls {
  static void f(std::size_t);
};

template <typename T>
void Cls<T>::f(decltype(sizeof(T))) { } // sizeof(int) works instead

奇怪的是,如果声明和定义匹配并且两者使用decltype(sizeof(T))它成功编译,我可以static_assert返回类型为size_t。以下编译成功:

#include <type_traits>

template <typename T>
struct Cls {
  static decltype(sizeof(T)) f();
};

template <typename T>
decltype(sizeof(T)) Cls<T>::f() { return 0; }

static_assert(std::is_same<std::size_t, decltype(Cls<int>::f())>{}, "");

用另一个例子更新。这不是一种依赖类型,但仍然失败。

template <int I>
struct Cls {
  static int f();
};

template <int I>
decltype(I) Cls<I>::f() { return I; }

如果我在定义和声明中都使用decltype(I),那么如果我在定义和声明中都使用int它会起作用,但两者的不同会失败。

更新2: 一个类似的例子。如果Cls更改为不是类模板,则会成功编译。

template <typename>
struct Cls {
  static int f();
  using Integer = decltype(Cls::f());
};

template <typename T>
typename Cls<T>::Integer Cls<T>::f() { return I; }

更新3: M.M.的另一个失败的例子。非模板类的模板化成员函数。

struct S {
  template <int N>
  int f();
};

template <int N>
decltype(N) S::f() {}

为什么声明和定义只是不同意依赖类型是非法的?即使类型本身不依赖于上面的template <int I>,为什么会受到影响?

0 个答案:

没有答案