在注视GCC 4.9.0版本改变了这里,我惊喜地阅读以下; 在C++的"新语言和语言特定改进"部分下:
G ++支持N3889的§4.1.2和§5.1.1:Concepts Lite Specification所规定的无约束泛型函数.简而言之,auto可以用作任何函数声明符的参数声明中的类型说明符,以便引入隐式函数模板参数,类似于通用lambdas.
// the following two function declarations are equivalent
auto incr(auto x) { return x++; }
template <typename T>
auto incr(T x) { return x++; }
Run Code Online (Sandbox Code Playgroud)
我构建了GCC 4.9.0,我的初始测试按预期工作.我相信Concepts Lite将继续以某种方式辅助即将推出的C++ 14规范.是否有任何"无约束通用函数"计划成为C++的一部分?
我想我会尝试耐人寻味的可表示的,仿函数包定义Monad和Comonad实例给出的函子data Pair a = Pair a a是由表示的Bool; 正如我之前关于矢量monad的问题的答案中提到的那样.
我注意到的第一件事情是让我的类型的实例Representable,我不仅要界定tabulate和index,同时也保证了我喜欢的类型是的一个实例Indexable,Distributive,Keyed,Apply,Applicative,和Functor类型类.好了,好了,index完成的定义Indexable和<.>功能Apply可以使用<*>从Applicative; 并且Functor实例是必需的并不奇怪.不过,我对我的怀疑实例Keyed和Distributive.
data Pair a = Pair a a
deriving (Show,Eq)
instance Functor Pair where
fmap f (Pair x y) = Pair …Run Code Online (Sandbox Code Playgroud) 有了像Foo这样的课程:
struct Foo { static const int i = 9; };
Run Code Online (Sandbox Code Playgroud)
我发现GCC 4.5将拒绝以下内容
Foo f;
int x = decltype(f)::i;
Run Code Online (Sandbox Code Playgroud)
如果我使用中间typedef,它将起作用,例如:
typedef decltype(f) ftype;
int x = ftype::i;
Run Code Online (Sandbox Code Playgroud)
但我更喜欢保持命名空间的清洁.我认为优先权可能是一个问题,所以我也试过括号,但没有运气.它是不可能的,或者是否有一段语法可以帮助我?
以下代码不能使用G ++ 4.5或4.6(快照)进行编译.它将使用Digital Mars Compiler 8.42n进行编译.
template <int I>
struct Foo {
template <int J>
void bar(int x) {}
};
template <int I>
void test()
{
Foo<I> a;
a.bar<8>(9);
};
int main(int argc, char *argv[]) {
test<0>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误消息是:
bugbody.cpp: In function 'void test() [with int I = 0]':
bugbody.cpp:16:11: instantiated from here
bugbody.cpp:11:3: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<'
Run Code Online (Sandbox Code Playgroud)
程序是否有效C++?
如果参数是C++函数对象(仿函数),我如何静态推导出?
template <typename F>
void test(F f) {}
Run Code Online (Sandbox Code Playgroud)
我试过了is_function<F>::value,但这不起作用.它似乎也没有is_functor特质,所以也许这是不可能的.我似乎只是在寻找一个特定的成员函数,在本例中是函数调用操作符:F::operator().
我使用的许多Parsec组合器都是这样的类型:
foo :: CharParser st Foo
Run Code Online (Sandbox Code Playgroud)
CharParser在这里定义为:
type CharParser st = GenParser Char st
Run Code Online (Sandbox Code Playgroud)
CharParser因此是一个类型的同义词GenParser,其本身在此定义为:
type GenParser tok st = Parsec [tok] st
Run Code Online (Sandbox Code Playgroud)
GenParser然后是另一种类型的同义词,使用Parsec,在此定义为:
type Parsec s u = ParsecT s u Identity
Run Code Online (Sandbox Code Playgroud)
所以Parsec部分应用程序ParsecT本身在此处列出类型:
data ParsecT s u m a
Run Code Online (Sandbox Code Playgroud)
以及单词:
"ParsecT suma是一个解析器,具有流类型s,用户状态类型u,底层monad m和返回类型a."
什么是潜在的monad?特别是,当我使用CharParser解析器时它是什么?我无法看到它在堆栈中的插入位置.是否存在与使用Haskell中的Monadic Parsing中的列表monad 从一个模糊解析器返回多个成功解析的关系?
如果我有一个Haskell ADT,例如:
data Foo
= A Int Double
| B Bool [Integer]
| C (Maybe String) Float
Run Code Online (Sandbox Code Playgroud)
的A,B和C被称为数据构造 ; 有时作为价值构造者.但是正确的名称是什么:
B Bool [Integer]; 和Doublein A或[Integer]in B?haskell functional-programming terminology algebraic-data-types
在下面的C++代码中,foobar首先为单个double参数定义,然后再为单个参数类型定义Foo.两者都在全局命名空间中定义.
在one命名空间内foobar,使用单个参数类型定义了进一步的重载Bar.从这个版本中foobar,一个不合格的调用foobar与double参数(42.0)将失败.类似的调用foobar,这次使用(::)范围解析运算符限定,也使用double参数,但是会成功.
另一方面,foobar带有类型参数的非限定调用Foo成功.使用范围解析运算符限定foobar的Foo参数调用也会成功.
为什么这两种情况的表现不同?我同时使用gcc 4.7和clang ++ 3.2.
struct Foo {};
struct Bar {};
double foobar(double x) { return x; }
Foo foobar(Foo f) { return f; }
namespace one {
Bar foobar(Bar b) {
//foobar(42.0); // error: can't convert to Bar
::foobar(42.0);
Foo f;
foobar(f); // no problem
::foobar(f);
return …Run Code Online (Sandbox Code Playgroud) Haskell中的列表可能如下所示:
data List a = Nil | Cons a (List a)
Run Code Online (Sandbox Code Playgroud)
类型理论解释是:
??.??.1+??
Run Code Online (Sandbox Code Playgroud)
它将列表类型编码为仿函数的固定点.在Haskell中可以表示:
data Fix f = In (f (Fix f))
data ListF a b = Nil | Cons a b
type List a = Fix (ListF a)
Run Code Online (Sandbox Code Playgroud)
我很好奇早期的μBinder的范围.外部作用域中绑定的名称是否仍可在内部作用域中使用?比如,以下是一个有效的表达式:
??.1+(??.1+??)?
Run Code Online (Sandbox Code Playgroud)
......也许它是一样的:
??.??.1+(1+??)?
Run Code Online (Sandbox Code Playgroud)
...但是,当重用名称时,情况会如何变化:
??.??.1+(??.1+??)?
Run Code Online (Sandbox Code Playgroud)
以上都是常规类型吗?
虽然,例如,std::add_pointer是一元,但GCC 7.0.0(20160608)和Clang 3.9.0都接受以下代码:
template <typename ...Ts>
struct tc1 {
using a = std::add_pointer<Ts...>;
};
Run Code Online (Sandbox Code Playgroud)
但是,虽然以下代码被Clang接受,但GCC拒绝了:
template <typename ...Ts>
struct tc2 {
template <typename ...Us>
using b = std::add_pointer<Ts...,Us...>;
};
Run Code Online (Sandbox Code Playgroud)
这是有效的C++吗?从语法上讲,我可以想象当包装是空的时候逗号是一个问题,但可能在其他场合被删除了; 例如,std::common_type接受零个或多个参数,以下任何一个编译器都没有问题:
template <typename ...Ts>
struct tc3 {
template <typename ...Us>
using c = std::common_type<Ts...,Us...>;
};
Run Code Online (Sandbox Code Playgroud)