- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图了解 std::enable_if 是如何工作的 inn 模板参数。
#include <type_traits>
#include <iostream>
#include <memory>
using namespace std;
class Interface {};
class Value {};
class Stream
{
public:
template<typename T,
typename enable_if<
is_base_of< Interface, T>{}
>::type* = nullptr>
void
write(const shared_ptr<T>& v)
{
cerr << "Writing interface class" << endl;
}
template<typename T,
typename enable_if<
is_base_of< Value, T>{}
>::type* = nullptr>
void
write(const shared_ptr<T>& v)
{
cerr << "Writing value class" << endl;
}
};
class UserI : public Interface{};
class User : public Value{};
int main(int, char**)
{
auto interface = make_shared<UserI>();
auto value = make_shared<User>();
Stream s;
s.write(interface);
s.write(value);
return 0;
}
他们我试图通过提供自定义特征来检查对象是接口(interface)还是值实例来简化代码。
#include <type_traits>
#include <iostream>
#include <memory>
using namespace std;
class Interface {};
class Value {};
template<typename T>
struct is_interface
{
const static bool value = is_base_of< Interface, T>::value;
};
template<typename T>
struct is_value
{
const static bool value = is_base_of< Value, T>::value;
};
class Stream
{
public:
template<typename T,
typename enable_if<
is_interface<T>{}
>::type* = nullptr>
void
write(const shared_ptr<T>& v)
{
cerr << "Writing interface class" << endl;
}
template<typename T,
typename enable_if<
is_value<T>{}
>::type* = nullptr>
void
write(const shared_ptr<T>& v)
{
cerr << "Writing value class" << endl;
}
};
class UserI : public Interface{};
class User : public Value{};
int main(int, char**)
{
auto interface = make_shared<UserI>();
auto value = make_shared<User>();
Stream s;
s.write(interface);
s.write(value);
return 0;
}
但是第二个版本编译失败,出现以下错误:
test_t2.cc: In function ‘int main(int, char**)’:
test_t2.cc:58:26: error: no matching function for call to ‘Stream::write(std::shared_ptr<UserI>&)’
s.write(interface);
^
test_t2.cc:58:26: note: candidates are:
test_t2.cc:32:9: note: template<class T, typename std::enable_if<is_interface<T>{}>::type* <anonymous> > void Stream::write(const std::shared_ptr<_Tp1>&)
write(const shared_ptr<T>& v)
^
test_t2.cc:32:9: note: template argument deduction/substitution failed:
test_t2.cc:30:28: error: could not convert template argument ‘is_interface<UserI>{}’ to ‘bool’
>::type* = nullptr>
谁能解释一下第二个版本的问题是什么?
最佳答案
typename enable_if<
is_base_of< Interface, T>{}
>::type* = nullptr
之所以可行,是因为 std::is_base_of
提供 operator bool
将其实例隐式转换为 bool
.你的特征没有提供,所以使用 is_interface<T>{}
作为bool
无效。
你可以写成operator bool
为你的特质,但简单的解决方法就是使用 ::value
相反:
template<typename T,
typename enable_if<
is_interface<T>::value //here
>::type* = nullptr>
void
write(const shared_ptr<T>& v)
就我个人而言,我认为在您的情况下,标签分派(dispatch)方法会更清晰且更易于维护。这是一个可能的实现:
class Stream
{
private:
struct interface_tag{};
struct value_tag{};
//if you ever need more tags, add them here
struct invalid_tag{};
template <typename T>
struct get_tag {
static interface_tag tagger (Interface*);
static value_tag tagger (Value*);
//add any mappings for other tags
static invalid_tag tagger (...);
using tag = decltype(tagger(std::declval<T*>()));
};
//convenience alias
template <typename T> using tag_t = typename get_tag<T>::tag;
public:
//clean public interface
template <typename T>
void write (const shared_ptr<T>& v) {
write(v, tag_t<T>{});
}
private:
//no more horrible std::enable_if
template<typename T>
void
write(const shared_ptr<T>& v, interface_tag)
{
cerr << "Writing interface class" << endl;
}
template<typename T>
void
write(const shared_ptr<T>& v, value_tag)
{
cerr << "Writing value class" << endl;
}
};
如果您需要有关此方法的任何说明,请询问。
关于c++ - enable_if 模板特化自定义特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33083011/
我正在使用这样的模板别名: template ::value>::type> using vec2 = std::pair; template ::value>::type> using vec3 =
基本问题陈述 我正在学习 SFINAE。我尝试了一个非常简单的 enable_if : // 1: A foo() that accepts arguments that are derived fr
在language reference of std::enable_if at cppreference包括以下注释 Notes A common mistake is to declare two
我对 SFINAE 有基本的了解,我想我理解了很多关于如何 std::enable_if 的例子。利用它来选择函数模板特化,但我很难理解它如何用于类模板。 以下例子来自cppreference.com
这有什么问题? 我认为这应该在使用 enable if 时起作用??? 帮助?? 不应该排除第二个构造函数吗? #include #include #include template class
我试图在模板类中声明函数,以便函数声明依赖于模板类型参数。 template struct Block { static bool parse(int32_t index,
我正在尝试一种基于类模板参数来专门化成员函数的方法,而不必在类上使用 SFINAE(并导致代码重复或创建另一个类)。 由于两个模板参数不能是可选的,并且参数 enable_if 在指南中是不受欢迎的,
我遇到一个问题,未知代码正在使用试图在编译时和运行时取消引用类型的元模板。这意味着,它们遍历指针层次结构直到找到匹配器。 现在通常这很好用。但是当用户传递类似的东西时: typedef struct
我试图了解 std::enable_if 是如何工作的 inn 模板参数。 #include #include #include using namespace std; class Inter
有谁知道为什么下面的代码可以编译 static const size_t CONSTANT = /* ... */; template = 0 > res_type foo() { // ...
我有一个类定义为: template class AdjacencyList; 其中 V 和 E 分别是顶点和边值的类型。 我目前正在尝试在 AdjacencyList 中定义以下成员函数: std
我有以下代码无法在 VC2010 上编译: #include using namespace std; template typename enable_if::type foo() { retu
为什么编译器对 std::tuple 的访问者具有以下定义顺序很重要 namespace TupleVisit{ //This function SHOULD BE DEFINED S
我想使用 type_traits 是否通过 shared_ptr 重载。 struct A { A(int i) : x(i) {} int x; }; int main() {
作为一个实验,我试图使一个没有参数的 void 成员函数根据类模板参数改变行为: #include #include template class MyClass { public: void
我正在使用 enable_if 语句来删除考虑中的可能方法。 #include "gmpxx.h" #include template struct is_ring_field { }; temp
是否有任何“更干净”的方式(我的意思是减少重复代码)来编写以下内容? template class Test { struct Foo1 { int a; }; struct F
在C ++中,请考虑以下示例: template struct q; template struct q { q() { cout struct q {
我对 std::enable_if 很陌生,想知道如何使用它。我有一个模板类: template class foo { } 现在我只想在 a + b 等于 10 时实例化它。我可以使用 std::e
我最近遇到了一个有趣的 enable_if 用法版本,它用于有条件地启用具有更好可读性的函数,因为该函数的返回类型不是 enable_if 的一部分(请参阅 cleaner_usage): #incl
我是一名优秀的程序员,十分优秀!