Code:
#include <iostream>
template<typename T>
class MyRNG{
public:
T Rand(){return T();};
};
template<typename RNG, typename = void>
struct GetDataTypeOf;
template<typename RNG>
struct GetDataTypeOf<RNG, decltype(std::declval<RNG>().Rand())> {
typedef decltype(std::declval<RNG>().Rand()) type;
};
template<typename RNG>
using DataTypeOf = typename GetDataTypeOf<RNG>::type;
int main(){
std::cout << typeid(DataTypeOf<MyRNG<int>>).name() << std::endl;
}
Error:
incomplete type is not allowed
using DataTypeOf = typename GetDataTypeOf<RNG>::type;
^
detected during instantiation of type "DataTypeOf<MyRNG<int>>" at line 22
It seems that GetDataTypeOf<MyRNG<int>> does not match any of the specialized class definitions. Why could that be?
Compiler: gcc 9.4.0
The problem is that
decltype(std::declval<RNG>().Rand())is notvoid. This means that you've provided the specialization not forvoidbut for the return typeT.One way to solve this is to add
voidto do explicit conversion so that the specialization becomes a specialization forvoidas shown below:Demo