我试图任意"绑定"模板参数,但遇到了一个优雅的问题.
为了直接解决潜在的问题,gcc 6.2有以下问题,但从逻辑上讲,我认为它没有问题......
template<template<typename, typename> P, typename A, typename B>
struct foo {
static constexpr bool value = P<A, B>::value;
};
template<typename...Ts>
struct bar {
static constexpr bool value = true;
};
Run Code Online (Sandbox Code Playgroud)
... foo给出bar如foo<bar, void, void>应导致的实例化bar<void, void>(这是有效的),谁的value部件true,因此foo<bar, void, void>::value同样是true.实际上,这应该(在我看来)导致实例化的结构在概念上类似于......
struct bar<void, void> {
static constexpr bool value = true;
};
struct foo<bar, void, void> {
static constexpr bool value = bar<void, …Run Code Online (Sandbox Code Playgroud) 虽然有很多东西浮出水面来获取任何模板化回调函数/方法的返回类型(当然包括lambdas),但我很难找到有关解析lambda函数的完整调用签名的信息.至少在gcc 4.7中,它似乎是一个边缘情况,正常的技巧(见下文)不起作用.这是我到目前为止所做的事情(当然是一个精简版)......
template<typename Sig>
struct invokable_type { };
template<typename R, typename...As>
struct invokable_type<R(As...)> {
static constexpr size_t n = sizeof...(As);
typedef R(callable_type)(As...);
template<size_t i>
struct arg {
typedef typename peel_type<i, As...> type;
};
};
Run Code Online (Sandbox Code Playgroud)
peel_type<size_t, typename...>为简洁起见,这里不包括它,但它是一个简单的参数类型削皮器(我认为有一个内置于C++ 11,但我从来没有费心去看).这个问题并不重要.
然后,当然,特(和进一步的性质/类型定义),用于可调用类型如无数存在R(*)(As...),R(&)(As...),(R(T::*)(As...),std::function<R(As...)>,方法CV限定符,方法左值/右值限定符,等等等等等等
然后,在路上的某个地方,我们有一个可爱的功能或方法(功能在这里,无关紧要),看起来像......
template<typename C, typename...As>
static void do_something(C&& callback, As&&...as) {
do_something_handler<invokable_type<C>::n, As...>::something(std::forward<C>(callback), std::forward<As>(as)...);
}
Run Code Online (Sandbox Code Playgroud)
没关系是什么do_something_handler......它完全不重要.问题在于lambda函数.
对于我专门用于的所有可能的通用可调用签名(看起来只是非STL仿函数),当do_something()它们作为第一个参数(模板推导完全有效)调用时,这种方法非常有效.但是,lambda函数会导致未捕获的类型签名,从而导致invokable_type<Sig>被使用,这意味着类似于::n并且::args<0>::type根本不存在的东西.
不是问题的例子......
void something(int x, int y) { …Run Code Online (Sandbox Code Playgroud) 我正在玩弄一个想法,我遇到了一个我真正摸不着头脑的问题.在我开始将这个想法迁移到更大的框架之前,我希望有人能给我一个明确的(最好引用的)解释.
我正在进行以下实验:
/*
* gcc -Wall -O0 -g -std=c++11 main.cc -lstdc++ -lm -o mathras
* clang++ -Wall -O0 -g -std=c++11 main.cc -lstdc++ -lm -o mathras
*/
#include <type_traits>
#include <functional>
template<typename U, typename V>
struct is_comparable {
static constexpr bool value = (std::is_integral<U>::value && std::is_integral<V>::value) || (std::is_floating_point<U>::value && std::is_floating_point<V>::value);
};
template<typename T>
class interval {
public:
inline interval();
inline interval(const T& x);
inline interval(const T& min, const T& max);
public:
template<typename U>
constexpr typename std::enable_if<!is_comparable<T, U>::value, bool>::type
operator==(const interval<U>&) const …Run Code Online (Sandbox Code Playgroud)