考虑这个非法代码:
template <int... Is>
struct Object {
void foo() const;
};
template <int... Js>
void Object<0, Js...>::foo() {/*Do whatever*/}
当第一个模板参数为0时,我们想要专门化foo(),并且如果第二个参数是3,那么我们想要专门化foo(),第三个int是1.所以我找到的解决方案(不确定它是否是最佳方法)如下:
#include <iostream>
template <int...> struct Foo;
template <int... Is>
struct Object {
int ID; // This member is just to illustrate the case when 'this' is needed in foo().
friend struct Foo<Is...>;
void foo() const {Foo<Is...>::execute(this);} // Pass 'this' in case it is needed.
};
template <int... Is>
struct Foo<0, Is...> {
static void execute (const Object<0, Is...>* object) {std::cout << "First int = 0, ID = " << object->ID << ".\n";}
};
template <int N, int... Is>
struct Foo<N, 3, Is...> {
static void execute (const Object<N, 3, Is...>* object) {std::cout << "Second int = 3, ID = " << object->ID << ".\n";}
};
template <int M, int N, int... Is>
struct Foo<M, N, 1, Is...> {
static void execute (const Object<M, N, 1, Is...>* object) {std::cout << "Third int = 1, ID = " << object->ID << ".\n";}
};
int main() {
Object<0,5,8,2>{4}.foo();
Object<4,3,2,5,3>{2}.foo();
Object<4,2,1>{0}.foo();
}
首先,这个解决方案有什么好处?接下来,如果我们尝试Object<0,3,1,4>{8}.foo();
因为规范未完成,现在会出现问题。所以,让我们说最早匹配的专业int将始终优先。因此,在这种情况下,Object<0,3,1,4>{8}.foo();
应该运行第一个特化,因为0,而Object<9,3,1,4>{8}.foo();
应该运行第二个特化,因为3,依此类推。如何执行该规则?
答案 0 :(得分:1)
评论和提示。
我的方法还可以。由于我们没有对所有功能进行部分模板专业化。
然后关于Object<0,3,1,4>{8}.foo()
,这给出了模糊的部分特化(在Clang 3.6上)。为了解决这个问题,我最后添加了另一个部分特化
template <int... Is>
struct Foo<0, 3, Is...> {
static void execute (const Object<0, 3, Is...>* object) {std::cout << "First int = 0, second = 3, ID = " << object->ID << ".\n";}
};
另一种可能性是使用std :: integer_sequence。我现在必须放弃,以下不是解决方案,只是开胃菜......
#include <utility>
#include <iostream>
template <class S1, class S2>
struct seq_lt
{
enum {value = 0} ;
} ;
template <int I1, int ...S1, int I2, int ...S2>
struct seq_lt<std::integer_sequence<int, I1, S1...>,
std::integer_sequence<int, I2, S2...>>
{
enum {value = (I1 < I2 ? 1 : 0)} ;
} ;
int main(int argc, char *argv[])
{
std::integer_sequence<int, 1, 2, 3> seq1 ;
std::integer_sequence<int, 2, 3> seq2 ;
std::cout << "seq_lt " << seq_lt<decltype(seq1), decltype(seq2)>::value << std::endl ;
std::cout << "seq_lt " << seq_lt<decltype(seq2), decltype(seq1)>::value << std::endl ;
}
答案 1 :(得分:1)
我建议只使用error Error: No compatible version found: bower-endpoint-parser@'^0.2.2'
1073 error Valid install targets:
1073 error ["0.1.0-rc.1","0.1.0","0.2.0","0.2.1","0.2.2"]
1073 error at installTargetsError (C:\Users\myname\node-0.10.4\node-0.10.4\node_modules\npm\lib\cache.js:685:10)
1073 error at C:\Users\myname\node-0.10.4\node-0.10.4\node_modules\npm\lib\cache.js:607:10
1073 error at saved (C:\Users\myname\node-0.10.4\node-0.10.4\node_modules\npm\node_modules\npm-registry-client\lib\get.js:138:7)
1073 error at Object.oncomplete (fs.js:107:15)
1074 error If you need help, you may report this log at:
1074 error <http://github.com/isaacs/npm/issues>
1074 error or email it to:
1074 error <npm-@googlegroups.com>
1075 error System Windows_NT 6.1.7601
1076 error command "C:\\Users\\myname\\node-0.10.4\\node-0.10.4\\\\node.exe" "C:\\Users\\myname\\node-0.10.4\\node-0.10.4\\node_modules\\npm\\bin\\npm-cli.js" "install" "bower"
1077 error cwd C:\Users\myname\BowerJS
1078 error node -v v0.10.4
1079 error npm -v 1.2.18
语句。无论如何,编译器可能会优化它们(假设您已启用优化)。
换句话说,只需做这样的事情:
if
你会得到几乎相同的效果,你的代码会更加清晰。
答案 2 :(得分:1)
这个解决方案的灵感来自于Marom的第二个建议,同时也受到了celticminstrel解决方案的启发。
#include <iostream>
#include <type_traits>
template <std::size_t, typename T, T...> struct NthValue;
template <typename T, T First, T... Rest>
struct NthValue<0, T, First, Rest...> : std::integral_constant<T, First> {};
template <std::size_t N, typename T, T First, T... Rest>
struct NthValue<N, T, First, Rest...> : NthValue<N - 1, T, Rest...> {};
template <int... Is>
struct Object {
void foo() const {fooHelper (typename Map<Is...>::type{});}
private:
template <int...> struct Map;
template <int, int> struct MappedType {};
struct Default {};
void fooHelper (const MappedType<0,0>&) const {std::cout << "First int = 0.\n";}
void fooHelper (const MappedType<1,3>&) const {std::cout << "Second int = 3.\n";}
void fooHelper (const MappedType<2,1>&) const {std::cout << "Third int = 1.\n";}
void fooHelper (const Default&) const {std::cout << "Default case.\n";}
};
template <int... Ns>
template <int... Is>
struct Object<Ns...>::Map {
using type = typename std::conditional<NthValue<0, int, Is...>::value == 0,
MappedType<0,0>,
typename std::conditional<NthValue<1, int, Is...>::value == 3,
MappedType<1,3>,
typename std::conditional<NthValue<2, int, Is...>::value == 1,
MappedType<2,1>,
Default
>::type
>::type
>::type;
};
int main() {
Object<0,5,8,2>().foo(); // First int = 0.
Object<4,3,2,5,3>().foo(); // Second int = 3.
Object<4,2,1>().foo(); // Third int = 1.
Object<0,3,1,4>().foo(); // First int = 0.
Object<9,3,1,4>().foo(); // Second int = 3.
Object<9,9,9>().foo(); // Default case.
}
也没有运行时开销。