我有一个函数,它采用模板类型来确定返回值。有没有办法在编译时告诉模板类型是否是模板类的某些实例化?
实施例
class First { /* ... */ };
template <typename T>
class Second { /* ... */ };
using MyType = boost::variant<First, Second<int>, Second<float>>;
template <typename SecondType>
auto func() -> MyType {
static_assert(/* what goes here?? */, "func() expects Second type");
SecondType obj;
// ...
return obj;
}
MyType obj = func<Second<int>>();
我知道可以通过
解决这个问题template <typename T>
auto func() -> MyType {
static_assert(std::is_same<T, int>::value || std::is_same<T, float>::value,
"func template must be type int or float");
Second<T> obj;
// ...
return obj;
}
MyType obj = func<int>();
如果有一种方法可以测试某个类型是否是模板类的实例化,我只是好奇一般?因为如果MyType
最终有6 Second
个实例,我不想测试所有可能的类型。
答案 0 :(得分:5)
这是一个选项:
#include <iostream>
#include <type_traits>
#include <string>
template <class, template <class> class>
struct is_instance : public std::false_type {};
template <class T, template <class> class U>
struct is_instance<U<T>, U> : public std::true_type {};
template <class>
class Second
{};
int main()
{
using A = Second<int>;
using B = Second<std::string>;
using C = float;
std::cout << is_instance<A, Second>{} << '\n'; // prints 1
std::cout << is_instance<B, Second>{} << '\n'; // prints 1
std::cout << is_instance<C, Second>{} << '\n'; // prints 0
}
它基本上专门针对模板实例化的类型is_instance
结构。
答案 1 :(得分:2)
另一种选择,接受亨利的评论:
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#dados">Dados Cliente</a></li>
<li><a data-toggle="tab" href="#endereco">Endereço Cliente</a></li>
<li><a data-toggle="tab" href="#login">Login Cliente</a></li>
</ul>
<div class="tab-content">
<div id="dados" class="tab-pane fade in active">
<div class="form-group">
<label>Nome</label>
<h:inputText value="#{usuarioMB.cliente.nome}" styleClass="form-control" />
</div>
</div>
<div id="endereco" class="tab-pane fade">
</div>
<div id="login" class="tab-pane fade">
<div class="form-group">
<label>Email</label>
<h:inputText value="#{usuarioMB.usuario.email}" styleClass="form-control" />
</div>
<div class="form-group">
<label>Senha</label>
<h:inputSecret styleClass="form-control" value="#{usuarioMB.usuario.senha}" />
</div>
</div>
</div>
答案 2 :(得分:0)
对@RichardHodges答案的另一种改进:通常,人们不仅希望捕获普通类型,而且还希望捕获所有 cv合格和 ref合格类型
以不同的方式输入,如果is_instance<A, Second>{}
为true,则is_instance<A const&, Second>{}
或is_instance<A&&, Second>{}
也应为true。该线程中的当前实现不支持该功能。
以下代码通过添加另一个间接和一个std::decay_t
来说明所有cv-ref限定的类型:
namespace
{
template <typename, template <typename...> typename>
struct is_instance_impl : public std::false_type {};
template <template <typename...> typename U, typename...Ts>
struct is_instance_impl<U<Ts...>, U> : public std::true_type {};
}
template <typename T, template <typename ...> typename U>
using is_instance = is_instance_impl<std::decay_t<T>, U>;
用作
#include <iostream>
template <typename ...> struct foo{};
template <typename ...> struct bar{};
int main()
{
std::cout << is_instance<foo<int>, foo>{} << std::endl; // prints 1
std::cout << is_instance<foo<float> const&, foo>{} <<std::endl; // prints 1
std::cout << is_instance<foo<double,int> &&, foo>{} << std::endl; // prints 1
std::cout << is_instance<bar<int> &&, foo>{} << std::endl; // prints 0
}