我在定义中使用推断出的返回类型来解析与声明相同的类型。这有效:
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>
,为什么会受到影响?