我想要能够使用的模板,扣除实现如下:

GCPtr<A> ptr1 = GC::Allocate();
GCPtr<B> ptr2 = GC::Allocate();

而不是(我目前有):

GCPtr<A> ptr1 = GC::Allocate<A>();
GCPtr<B> ptr2 = GC::Allocate<B>();

我的当前分配的功能看起来是这样的:

class GC
{
public:
    template <typename T>
    static GCPtr<T> Allocate();
};

这将有可能敲掉多余的 <A><B>?

有帮助吗?

解决方案

不能完成。返回的类型不一部分类型的扣除,这是相当的结果有匹配的适当模板签名。你可以,但是,隐藏的大多数用途为:

// helper
template <typename T>
void Allocate( GCPtr<T>& p ) {
   p = GC::Allocate<T>();
}

int main()
{
   GCPtr<A> p = 0;
   Allocate(p);
}

这是否意语法是实际上任何更好或者更糟的是,比初始的 GCPtr<A> p = GC::Allocate<A>() 是另一个问题。

P.S.c++11会让你跳一种类型的声明:

auto p = GC::Allocate<A>();   // p is of type GCPtr<A>

其他提示

我唯一能想到的:使分配一个非模板,返回一个非模板代理的对象,有一个模板转换操作者,它不会真正的工作:

template <class T>
struct GCPtr
{

};

class Allocator
{
public:
    template <class T>
    operator GCPtr<T>() { return GCPtr<T>(); }
};

class GC
{
public:
    static Allocator Allocate() { return Allocator(); }//could give a call-back pointer?
};

int main()
{
    GCPtr<int> p = GC::Allocate();
}

你可以走相反的路线。

如果你使用最新编译器(MSVC2010年这应该是在几天,或者当前版本的海湾合作委员会)和没头脑依靠C++0x特点:

auto ptr1 = GC::Allocate<A>();
auto ptr2 = GC::Allocate<B>();

会救你的额外 <A><B>, 只是不是在右边。:)

(这个答案是一样@UncleBens,但有一点更一般的,因为它完美的转任何论据。)

这是非常有用的语言,如haskell,例如, read 将采取一串为输入,将分析它根据希望返回的类型。

(在这里是 样本上的代码ideone.)

第一,开始与功能 foo 其返回的类型,我们希望推演出:

template<typename Ret>
Ret foo(const char *,int);
template<>
std::string foo<std::string>(const char *s,int) { return s; }
template<>
int         foo<int        >(const char *,int i) { return i; }

当问及对一串,它将返回的串,在其第一个参数。当问及对一个int,它将返回的第二个论点。

我们可以定义功能 auto_foo 这可以使用如下:

int main() {
        std::string s = auto_foo("hi",5); std::cout << s << std::endl;
        int         i = auto_foo("hi",5); std::cout << i << std::endl;
}

为了使这项工作,我们需要一个对象,将暂时储存功能的参数,并且运行的功能,当它被要求 转换 到希望返回的类型:

#include<tuple>

template<size_t num_args, typename ...T>
class Foo;
template<typename ...T>
class Foo<2,T...> : public std::tuple<T&&...>
{
public: 
        Foo(T&&... args) :
                std::tuple<T&&...>(std::forward<T>(args)...)
        {}
        template< typename Return >
        operator Return() { return foo<Return>(std::get<0>(*this), std::get<1>(*this)); }
};
template<typename ...T>
class Foo<3,T...> : std::tuple<T&&...>
{
public: 
        Foo(T&&... args) :
                std::tuple<T&&...>(std::forward<T>(args)...)
        {}
        template< typename Return >
        operator Return() { return foo<Return>(std::get<0>(*this), std::get<1>(*this), std::get<2>(*this)); }
};

template<typename ...T>
auto
auto_foo(T&&... args)
        // -> Foo<T&&...> // old, incorrect, code
        -> Foo< sizeof...(T), T&&...> // to count the arguments
{
        return              {std::forward<T>(args)...};
}

此外,上述工作的两-arg或三arg功能,这是不难看出如何延长。

这是一个很大的代码写!每个功能,你将适用这个,你可以写一个宏观,这不会给你的。像这样的东西在你的文件:

REGISTER_FUNCTION_FOR_DEDUCED_RETURN_TYPE(foo); // declares
                        // necessary structure and auto_???

然后你可以用 auto_foo 在你的程序。

在相同的方式你不能超载功能在返回时的类型,你不能这样做的模板,扣除。出于同样的原因-如果f()是一个模板载于返回的东西,什么类型的使用:

f();

你可以尝试使用宏观。除此之外,我看不出这是应该只有一个发言。

#define ALLOC(ptrname,type) GCPtr<type> ptrname = GC::Allocate<type>()

ALLOC(ptr1,A);

约翰内斯'点都是有效的。该>>的问题是很容易地固定的。但我认为具有逗号一部分的类型需要C99预处理器varargs扩展:

#define ALLOC(ptrname,...) GCPtr< __VA_ARGS__ > ptrname = GC::Allocate< __VA_ARGS__ >()

ALLOC(ptr1,SomeTemplate<int,short>);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top