我在理解std::result_ofC++ 0x中的需求时遇到了一些麻烦.如果我理解正确,result_of则用于获取调用具有某些类型参数的函数对象的结果类型.例如:
template <typename F, typename Arg>
typename std::result_of<F(Arg)>::type
invoke(F f, Arg a)
{
return f(a);
}
Run Code Online (Sandbox Code Playgroud)
我真的没有看到与以下代码的区别:
template <typename F, typename Arg>
auto invoke(F f, Arg a) -> decltype(f(a)) //uses the f parameter
{
return f(a);
}
Run Code Online (Sandbox Code Playgroud)
要么
template <typename F, typename Arg>
auto invoke(F f, Arg a) -> decltype(F()(a)); //"constructs" an F
{
return f(a);
}
Run Code Online (Sandbox Code Playgroud)
我能用这两种解决方案看到的唯一问题是我们需要:
难道我就在想,唯一的区别decltype和result_of是而第二个不第一个需要表达?
当我偶然发现这个问题时,我正在尝试使用C++ 0x可变参数模板:
template < typename ...Args >
struct identities
{
typedef Args type; //compile error: "parameter packs not expanded with '...'
};
//The following code just shows an example of potential use, but has no relation
//with what I am actually trying to achieve.
template < typename T >
struct convert_in_tuple
{
typedef std::tuple< typename T::type... > type;
};
typedef convert_in_tuple< identities< int, float > >::type int_float_tuple;
Run Code Online (Sandbox Code Playgroud)
当我尝试输入模板参数包时,GCC 4.5.0给出了一个错误.
基本上,我想将参数包"存储"在typedef中,而无需解压缩.可能吗?如果没有,是否有一些理由不允许这样做?
阅读这个问题让我想知道:是否存在禁止类模板重载的技术原因?
通过重载,我的意思是有几个模板具有相同的名称,但不同的参数,例如
template <typename T>
struct Foo {};
template <typename T1, typename T2>
struct Foo {};
template <unsigned int N>
struct Foo {};
Run Code Online (Sandbox Code Playgroud)
编译器设法处理重载的函数和函数模板,是不是可以将相同的技术(例如名称修改)应用于类模板?
起初,我认为这可能会在单独使用模板标识符时引起一些歧义问题,但唯一可能发生的情况是将其作为模板模板参数传递,因此参数的类型可用于选择合适的超载:
template <template <typename> class T>
void A {};
template <template <unsigned int> class T>
void B {};
A<Foo> a; // resolves to Foo<T>
B<Foo> b; // resolves to Foo<N>
Run Code Online (Sandbox Code Playgroud)
你认为这样的功能有用吗?是否存在一些"好"(即技术)原因,为什么在当前的C++中这是不可能的?
c++ templates overloading template-specialization language-lawyer
为什么无法引用void?我在C++标准中找到的唯一内容就是这一行,见8.3.2.1
指定类型"对cv void的引用"的声明符是不正确的.
为什么会那样?为什么我不能写一个接受一个"通用"的函数void&?
为了清楚起见,我没有任何有用的应用程序,使用引用void可能比使用模板更好,但我只是好奇禁止这个结构的基本原理.
为了澄清一点,我理解使用"按原样"引用"无效"将与取消引用指向void的指针一样毫无意义.不过,我可以把它转换为参考TO- sometype.这时候为了使用它,我能不能?事实上,我不明白为什么下面的代码片段可以工作......
void foo(void *data)
{
int *i = reinterpret_cast<int*>(data);
// do something with i
}
Run Code Online (Sandbox Code Playgroud)
......虽然这个不能:
void foo(void &data)
{
int &i = reinterpret_cast<int&>(data);
// do something with i
}
Run Code Online (Sandbox Code Playgroud) 对于C++新手来说,允许const成员函数在类引用的对象(通过指针或引用)上调用非const方法通常会让人感到困惑.例如,以下内容完全正确:
class SomeClass
{
class SomeClassImpl;
SomeClassImpl * impl_; // PImpl idiom
public:
void const_method() const;
};
struct SomeClass::SomeClassImpl
{
void non_const_method() { /*modify data*/ }
};
void SomeClass::const_method() const
{
impl_->non_const_method(); //ok because impl_ is const, not *impl_
};
Run Code Online (Sandbox Code Playgroud)
但是,如果constness传播到尖头对象,它有时会非常方便(我自愿使用PImpl习语,因为它是我认为"constness传播"非常有用的情况之一).
使用指针时,可以通过使用某种智能指针轻松实现这一点,操作符在constness上重载:
template < typename T >
class const_propagating_ptr
{
public:
const_propagating_ptr( T * ptr ) : ptr_( ptr ) {}
T & operator*() { return *ptr_; }
T const & operator*() const { return *ptr_; }
T * operator->() …Run Code Online (Sandbox Code Playgroud) Boost.Optional使用虚拟类型来允许构建未初始化的实例boost::optional<T>.调用此类型none_t,none为方便起见,已在头中定义了一个实例,允许我们编写如下代码:
boost::optional<int> uninitialized(boost::none);
Run Code Online (Sandbox Code Playgroud)
看一下定义none_t,我注意到它实际上是一个typedef,对应于某个伪结构的指向成员的指针:
namespace boost {
namespace detail { struct none_helper{}; }
typedef int detail::none_helper::*none_t ;
none_t const none = (static_cast<none_t>(0)) ;
} // namespace boost
Run Code Online (Sandbox Code Playgroud)
使用这样一个复杂的typedef比这样的简单空结构有什么好处?
namespace boost {
struct none_t {};
none_t const none;
} // namespace boost
Run Code Online (Sandbox Code Playgroud) 模板特化不考虑继承层次结构.例如,如果我专门Base化模板并将其实例化Derived,则不会选择特化(参见下面的代码(1)).
这可能是一个主要障碍,因为它有时会导致违反Liskov替代原则.例如,在工作时这个问题,我发现我不能使用Boost.Range算法具有std::sub_match虽然我可以用std::pair.由于sub_match公开继承pair,常识会指示我可以替换使用的sub_match所有地方pair,但由于使用模板专门化的特征类而失败.
我们可以通过使用部分模板特化enable_if和is_base_of(见代码(2))来克服这个问题.我是否总是喜欢这种解决方案而不是完全专业化,特别是在编写库代码时?我监督这种方法有什么缺点吗?这是您经常使用或经常使用的做法吗?
示例代码
(1)
#include <iostream>
struct Base {};
struct Derived : public Base {};
template < typename T >
struct Foo
{
static void f() { std::cout << "Default" << std::endl; }
};
template <>
struct Foo< Base >
{
static void f() { std::cout << "Base" << std::endl; }
};
int main()
{
Foo<Derived>::f(); // …Run Code Online (Sandbox Code Playgroud) 通常,我会使用boost::mpl::for_each<>()遍历a boost::mpl::vector,但这需要一个带有模板函数的仿函数,如下所示:
template<typename T> void operator()(T&){T::staticCall();}
我的这个问题是我不希望的物体T被实例化也for_each<>.我根本不需要T参数operator().有没有办法实现这一点,或者替代方法for_each<>是不将类型为T的对象传递给模板函数?
最理想的是,我希望operator()定义如下所示:
template<typename T> void operator()(){T::staticCall();}
当然,我不希望在通话之前对T进行实例化.任何其他提示/建议也欢迎.
我是一个熟练的程序员,使用JavaScript,但我不是大师.我知道你可以用它做一些非常强大的东西,除了相当基本的DOM操作之外我还没有看到太多东西.我想知道人们是否可以使用JavaScript提供一些传统设计模式概念的例子,例如Factory Method,Singleton等.在什么情况下这些模式将用于网络?
javascript singleton design-patterns strategy-pattern factory-method