MPL占位符在默认模板参数中替换
MPL placeholder replacement in default template parameter
我遇到一些麻烦,理解MPL占位符。
有人可以向我解释为什么此代码无法编译?
我希望数字0,1&2要打印,但是当编译器试图确定包装器的默认模板参数的类型时,似乎占位符并不能被实际类型替换。
#include <iostream>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/vector.hpp>
template <typename T> struct Traits;
template<> struct Traits<int> { typedef boost::mpl::int_<0> type; };
template<> struct Traits<char> { typedef boost::mpl::int_<1> type; };
template<> struct Traits<bool> { typedef boost::mpl::int_<2> type; };
template <typename T, typename Type=typename Traits<T>::type > struct Wrapper
{
Wrapper() { std::cout << "Value: " << Type::value << std::endl; }
T value;
};
int main()
{
typedef boost::mpl::inherit_linearly<
boost::mpl::vector<int, char, bool>,
boost::mpl::inherit<boost::mpl::_1, Wrapper<boost::mpl::_2> > >::type Object;
Object obj;
return 0;
}
这是GCC-4.1.2的错误(我知道...工作中的旧编译器)
# g++4 -I ../boost test.cpp -o test
test.cpp: In function 'int main()':
test.cpp:24: error: invalid use of undefined type 'struct Traits<mpl_::arg<2> >'
test.cpp:7: error: declaration of 'struct Traits<mpl_::arg<2> >'
test.cpp:24: error: template argument 2 is invalid
test.cpp:24: error: template argument 2 is invalid
test.cpp:24: error: template argument 2 is invalid
test.cpp:24: error: expected initializer before 'Object'
test.cpp:26: error: 'Object' was not declared in this scope
test.cpp:26: error: expected `;' before 'obj'
编辑:在下面的Acorbe回答之后,我制作了我的示例程序的一种变体,以说明为什么他的建议解决方案不符合我的需求。这澄清了我的追求。在这种情况下,我希望打印文本type_a,type_b,type_a。G 错误是相同的。
#include <iostream>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/vector.hpp>
enum WrapperType { TYPE_A, TYPE_B };
template <typename T> struct Traits;
template<> struct Traits<int> { typedef boost::mpl::int_<TYPE_A> type; };
template<> struct Traits<char> { typedef boost::mpl::int_<TYPE_B> type; };
template<> struct Traits<bool> { typedef boost::mpl::int_<TYPE_A> type; };
template <typename T, typename Type=typename Traits<T>::type > struct Wrapper;
template <typename T>
struct Wrapper<T, boost::mpl::int_<TYPE_A> >
{
Wrapper() : value (0) { std::cout << "TYPE_A" << std::endl; }
T value;
};
template <typename T>
struct Wrapper<T, boost::mpl::int_<TYPE_B> >
{
Wrapper() { std::cout << "TYPE_B" << std::endl; }
T value;
};
int main()
{
typedef boost::mpl::inherit_linearly<
boost::mpl::vector<int, char, bool>,
boost::mpl::inherit<boost::mpl::_1, Wrapper<boost::mpl::_2> > >::type Object;
Object obj;
return 0;
}
这是GCC-4.5.4
的错误# g++ -I ../boost test.cpp -o test
test.cpp: In functie ‘int main()’:
test.cpp:37:79: fout: invalid use of incomplete type ‘struct Traits<mpl_::arg<2> >’
test.cpp:9:34: fout: declaration of ‘struct Traits<mpl_::arg<2> >’
test.cpp:37:79: fout: template argument 2 is invalid
test.cpp:37:81: fout: template argument 2 is invalid
test.cpp:37:83: fout: template argument 2 is invalid
test.cpp:37:91: fout: expected initializer before ‘Object’
test.cpp:39:9: fout: ‘Object’ was not declared in this scope
test.cpp:39:16: fout: expected ‘;’ before ‘obj’
这是(部分)Clang -3.1的错误:
test.cpp:15:50: error: implicit instantiation of undefined template 'Traits<mpl_::arg<2> >'
template <typename T, typename Type=typename Traits<T>::type > struct Wrapper;
^
test.cpp:37:57: note: in instantiation of default argument for 'Wrapper<mpl_::arg<2> >' required here
boost::mpl::inherit<boost::mpl::_1, Wrapper<boost::mpl::_2> > >::type Object;
^~~~~~~~~~~~~~~~~~~~~~~
test.cpp:9:34: note: template is declared here
template <typename T> struct Traits;
我对您的代码进行了一些更改,将默认模板参数诱导的typedef
分解了两个更简单的typedef
s。
考虑一下:
template < typename T , typename Super_Type = Traits<T> > struct Wrapper
{
typedef typename Super_Type::type Type;
Wrapper() { std::cout << "Value: " << Type::value << std::endl; }
T value;
};
这样进行编译。我的怀疑是您的原始表达(尽管正确)是某种程度上的复杂性,无法通过编译器正确扩展。
Allight ...我似乎已经破解了...
经常,额外的抽象能够解决问题。
我创建了一个元函数类(GenWrapper),该类将传递给MPL :: Apply1与占位符。然后,那里的元功能将返回预期的包装器类型。
这是结果程序(第二版)。
感谢所有的帮助和指针。
#include <iostream>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/vector.hpp>
enum WrapperType { TYPE_A, TYPE_B };
template <typename T> struct Traits;
template<> struct Traits<int> { typedef boost::mpl::int_<TYPE_A> type; };
template<> struct Traits<char> { typedef boost::mpl::int_<TYPE_B> type; };
template<> struct Traits<bool> { typedef boost::mpl::int_<TYPE_A> type; };
template <typename T, typename Type = typename Traits<T>::type> struct Wrapper;
template <typename T>
struct Wrapper<T, boost::mpl::int_<TYPE_A> >
{
Wrapper() : value (0) { std::cout << "TYPE_A" << std::endl; }
T value;
};
template <typename T>
struct Wrapper<T, boost::mpl::int_<TYPE_B> >
{
Wrapper() { std::cout << "TYPE_B" << std::endl; }
T value;
};
struct genWrapper
{
template <typename T>
struct apply
{
typedef Wrapper<T> type;
};
};
int main()
{
typedef boost::mpl::inherit_linearly<
boost::mpl::vector<int, char, bool>,
boost::mpl::inherit<boost::mpl::_1, boost::mpl::apply1<genWrapper, boost::mpl::_2> > >::type Object;
Object obj;
return 0;
}
这是结果的输出:
# g++4 -I ../boost test.cpp -o test
# ./test
TYPE_A
TYPE_B
TYPE_A
相关文章:
- 模板参数替换失败,并且未完成隐式转换
- 如果可推导类型上有替换,可变参数模板类型推导会使编译器崩溃
- 将变量替换为可变参数模板
- 为表示一个或多个操作的C++函数的int参数寻找类型安全的替换
- 仅当一个参数中未使用 std::function 时,模板函数替换才有效
- 类似函数的宏参数名称替换是否保证永远不会发生?
- 模板参数推导/替换失败,lambda作为函数指针
- 为什么在 ctor 的参数列表中将成员"x"的类型替换为"decltype(x)"会破坏类模板参数推导?
- 为什么我的一个宏参数被替换为')'而不是标识符?
- 类模板参数推导失败会导致替换失败
- 使用"std::function"和先前推断的模板参数替换失败 - 为什么?
- 不能将模板参数替换为类型模板参数_Ty
- 模板参数替换令人惊讶?
- 将默认模板参数替换为别名
- 有没有办法用参数替换字符串,例如 C++ 中的 printf
- 要求子句是在声明中的参数替换后计算的
- 为什么模板参数替换的顺序很重要
- 依赖模板名称参数替换
- 模板默认参数替换失败 clang 3.3.
- 参数替换的C++规则