2016-04-29 48 views
15

通過使用模板模板參數,可以將模板類傳遞給類,而無需在其參數上指定類型。我想知道是否有一種方法可以將模板模板參數傳遞給函數的模板化簽名,以便能夠專門化該函數的哪個變體將被視爲前向。有沒有辦法將模板化函數簽名作爲模板模板參數

要清楚 - 我知道我不能這樣做:

template <class T> 
void foo() { /*...*/ } 

template <template <class...> class FooType> 
struct Foo { /*...*/ }; 

int main() { 
    Foo<decltype(foo)> f; 
} 

但不知何故,我想能的功能模板簽名傳遞給Foo。它甚至有可能嗎?

回答

7

在下面的例子中,有一個模板模板參數接受函數的首選簽名。
由於模板類的特殊性和缺少主體,因此只接受可調用類型。
這是一個什麼樣的OP居然問了一個概括:

#include<cassert> 

template<typename F> 
struct S; 

template<typename R, typename... Args> 
struct S<R(Args...)> { 
    using type = R(*)(Args...); 
}; 

template<template<typename> class F> 
struct T { 
    typename F<void(int)>::type ft; 
    typename F<double(double, double)>::type gt; 
}; 

void f(int) { } 
double g(double x, double y) { return x+y; } 

int main() { 
    T<S> t; 
    t.ft = f; 
    t.gt = g; 
    t.ft(42); 
    auto v = t.gt(1., 1.); 
    assert(v == 2.); 
} 
+1

是的'using'這裏的伎倆。這種方法似乎比使用''模板更清潔... –

+0

我可以問你,你使用它的目的是什麼?只是好奇...我看不到'T'的用法,我不能簡單地使用'S'。 – skypjack

+0

當然,這個問題從另一個存檔問題中提出:http://stackoverflow.com/questions/36655835/better-pattern-for-partial-specialization-disambiguation-precedence-chain/36657353#36657353我想提出一個通用標記這將能夠接受模板模板類和功能與給定的簽名...然後我意識到,這不是一個微不足道的任務... :) –

3

模板模板仍然是模板。

template <class T> 
void foo() { /*...*/ } 

template <typename T> 
struct Foo { /*...*/ }; 

int main() { 
    Foo<decltype(foo<int>)> f; 
} 
+0

我在傳遞函數模板簽名特別感興趣... –

3

如可在this answer

模板函數指針可以看出是在C++非法

C++標準說,在$ 14/​​1,

模板定義了一個類或函數族。

從鏈接的回答進一步的報價:

請注意,它並沒有說「模板定義的類系列,功能或函數指針

然而,你可以通過具體的功能指針,並專注於他們的簽名:

#include <iostream> 

template <class T> 
void foo(T) { } 

template <typename> 
struct Foo; 

template<typename T> 
struct Foo<void(T)> 
{ 
    void cb() { std::cout << "T\n"; } 
}; 

template<> 
struct Foo<void(int)> 
{ 
    void cb() { std::cout << "int\n"; } 
}; 

template<> 
struct Foo<void(double)> 
{ 
    void cb() { std::cout << "double\n"; } 
}; 

int main() 
{ 
    Foo<decltype(foo<int >)>().cb(); // outputs 'int' 
    Foo<decltype(foo<double>)>().cb(); // outputs 'double' 
    Foo<decltype(foo<char >)>().cb(); // outputs 'T' 
    return 0; 
} 
2

您不能將函數模板作爲參數傳遞。你可以做的是採取一個標籤參數產生拉姆達包裝一個函數模板:

template <class T> struct tag_t { using type = T; }; 

template <class T> 
void foo() { ... } 

template <class F> 
void call_func_with(F f) { 
    f(tag_t<int>{}); 
    f(tag_t<double>{}); 
} 

call_with_func([](auto tag) { foo<decltype(tag)::type>(); }); 

這裏,f(tag_t<X>{})結束調用foo<X>(),根據需要。

8

我不能相信這是不可能的,所以我搜索了一下,找到了一種方法去做我想要的東西。我用模板using與語法:

template <template<class... Args> class FooType> 
struct Foo { 
    FooType<int> ft; 
}; 

template <class Res, class... Args> 
using FooSignature = Res(*)(Args...); 

int foo() { 
    return 1; 
} 

int main() { 
    Foo<FooSignature> f; 
    f.ft = foo; 
} 

然而,這仍然留下這怎麼可能,因爲對面的標準規定的東西的問題。

相關問題