如果类模板可以实例化,那么是真的变量模板吗?
比方说,我有一个类模板A,它具有一个类型模板参数和一个主要的专业化名称:
Let's say I have a class template A that has one type template parameter, and a single primary specialization:
template<typename T> struct A {
/*...*/
};
对于某些 T
自变量 A< T>
将成功实例化,而对于其他参数则不会成功.
For some T
arguments A<T>
will instantiate successfully, for others it won't.
如果不修改或扩展 A
的定义,是否可以编写布尔变量模板:
Without modifying or extending the definition of A
, is it possible to write a bool variable template:
template<typename T>
constexpr bool WorksWithA = /*...*/;
如果 A< T>
可以成功实例化,那么 WorkWithA< T>
是真实的吗?
such that WorkWithA<T>
is true iff A<T>
would instantiate successfully?
更新
将此作为单独的问题发布:在C ++ 20中使用类型名需要/概念吗?
Posted this as separate question: Using typename in C++20 requires / concept?
#include <iostream>
template<typename T>
struct A {
using X = typename T::X;
};
template<typename T>
constexpr bool WorksWithA = requires { typename A<T>; };
struct GoodArg {
using X = int;
};
struct BadArg {
};
int main() {
std::cout << WorksWithA<GoodArg> << std::endl;
std::cout << WorksWithA<BadArg> << std::endl;
}
编译并运行:
$ clang++ --version
clang version 10.0.0-4ubuntu1
$ clang++ test.cc -std=c++20
$ ./a.out
1
1
这将输出 1 1
,预期输出是 1 0
吗?
This outputs 1 1
, expected output is 1 0
?
有什么作用?
这是一个好(也是正确的)问题,但我认为到目前为止,这个问题一般都没有答案.让我们假设类模板 A
就像这样:
This is a good (and right) question, but I think as up until now there is no answer for this question in general.
Lets assume the class template A
is simply like:
template<typename T>
class A{
public:
T variable;
}
此模板适用于大多数类型,但出于明显的原因,它不使用 T = void
实例化.现在,假设我们想使用SFINAE友好方法事先找到答案.
This template works with most of types but it does not instantiate with T = void
for the obvious reason. now lets assume we want to find that out before hand with a SFINAE friendly method.
找出类型是否可实例化的最佳工具是检查其是否具有大小,现在让我们定义类似于 std :: void_t
:
The best tool to find out if a type is instantiatable is to check whether it has a size, now Lets define a tool similar to std::void_t
:
template<size_t...> using void_size_t = void;
现在我们是否定义:
template< class, class = void >
struct pre_WorksWithA : std::false_type { };
template< class T >
struct pre_WorksWithA<T, void_size_t<sizeof(A<T>)>> : std::true_type { };
template<typename T>
constexpr bool WorksWithA = pre_WorksWithA<T>::value;
如果是 int
之类的普通类型,结果应为 true
.但是对于 void
, WorksWithA
和 pre_WorksWithA
都无法实例化,结果将是编译器的错误.
In case of a normal types like int
the result is true
which it should be. but in case of void
neither the WorksWithA
nor pre_WorksWithA
can instantiate and the result would be an error from the compiler.
因此,您可以看到,到目前为止,C ++基本上没有任何功能可以帮助我们知道类型是否可以实例化而不会给出错误?
So as you can see, up until now, basically there is no feature in C++ to help us know whether a type is instantiate-able or not without giving an error?