c++20 concept

Visual Studio 2019今天发布了16.3版本更新,加入了C++20的concept支持,在此记录一下concept的用法:

concept示例

1.限制只能打印int类型

//std::enable_if实现
template <typename T>
void print_int(std::enable_if_t<std::is_same_v<int, std::decay_t<T>>, T> v)
{
	std::cout << v << std::endl;
}

int main()
{
	print_int(1);			//error C2783: “void print_int(enable_if<std::is_same_v<int,decay<_Ty>::type>,T>::type)”: 未能为“T”推导 模板 参数
	print_int<int>(1);
	print_int<double>(1.0); //error C2672: “print_int”: 未找到匹配的重载函数
}
//concept实现
template <class T>
concept IntLimit = std::is_same_v<int, std::decay_t<T>>; //制约T塌陷后的类型必须与int相同

template <IntLimit T>
void print_int(T v)
{
	std::cout << v << std::endl;
}

int main()
{
	print_int(1);
	print_int(1.0); //error C2672: “print_int”: 未找到匹配的重载函数
}

可以看到concept比之前的实现更加简洁易懂。
2.require关键字

//限定只能调用存在name成员函数的类
class A
{
public:
	std::string_view name() const { return "A"; }
};

class B
{
public:
	std::string_view class_name() const { return "B"; }
};

template <typename T>
concept NameLimit = requires(T a)
{
	a.name();	//制约T的实例a必须要有name成员函数
};

template <NameLimit T>
void print_name(T a)
{
	std::cout << a.name() << std::endl;
}

int main()
{
	A a;
	B b;
	print_name(a);
	print_name(b); //error C2672 : “print_name”: 未找到匹配的重载函数
}
//限定只能调用返回值可以转换为std::string的函数
template <typename T>
concept ReturnLimit = requires(T t)
{
	{t()} -> std::convertible_to<std::string> ;	//函数返回值必须可以转换为std::string
	std::is_function<T>;						//T必须为函数
};

template <ReturnLimit T>
void print_string(T func)
{
	std::cout << func() << std::endl;
}

std::string str1()
{
	return "123";
}

constexpr const char* str2()
{
	return "str2";
}

std::basic_string<char8_t> str3()
{
	return u8"str3";
}

int main()
{
	std::string t;
	t = std::string_view("213");
	print_string(&str1);
	print_string(&str2);
	print_string(&str3); //error C2672: “print_string”: 未找到匹配的重载函数
	return 0;
}

concept可以和if constexpr结合使用

class A
{
public:
	constexpr std::string_view name() const { return "A"; }
};

class B
{
public:
	constexpr std::string_view class_name() const { return "B"; }
};

template <typename T>
concept CA = requires(T a)
{
	a.name();
};

template <typename T>
concept CB = requires(T b)
{
	b.class_name();
};

template <typename T>
void print_class(const T& t)
{
	if constexpr (CA<T>)
	{
		std::cout << t.name() << std::endl;
	}
	else if constexpr (CB<T>)
		std::cout << t.class_name() << std::endl;
}

int main()
{
	A a;
	B b;
	print_class(a);
	print_class(b);
	return 0;
}

打印出结果:
A
B

发布了16 篇原创文章 · 获赞 11 · 访问量 6675

猜你喜欢

转载自blog.csdn.net/oLuoJinFanHua12/article/details/101319056