C++ 模板元编程-确定函数参数
如果有人有更复杂的解决方案,那就太好了。非常感谢 ----------------------------------编辑------------------------------ 这个变通方法有点好(灵感来自Oisyn),它或多或少地结合了参数专门化和默认参数这两个方面的优点。可能也会快一点,因为它避开了if语句C++ 模板元编程-确定函数参数,c++,templates,template-meta-programming,C++,Templates,Template Meta Programming,如果有人有更复杂的解决方案,那就太好了。非常感谢 ----------------------------------编辑------------------------------ 这个变通方法有点好(灵感来自Oisyn),它或多或少地结合了参数专门化和默认参数这两个方面的优点。可能也会快一点,因为它避开了if语句 template<class T> class Object { Object baz(IF_ELSE<boolean_condition<T>
template<class T>
class Object {
Object baz(IF_ELSE<boolean_condition<T>::value, foo_class, int>::type param = 0) {
if (param == 0)
return Object();
else
return Object(param);
}
};
模板
类对象
{
公众:
结构使_非法{};
模板
对象(参数p){/*do stuff*/}
对象(){/*默认值*/}
模板
对象baz(标准::条件参数)
{返回对象(param);}
模板
对象baz(标准::条件值=0)
{返回对象();}
};
int main(){
对象对象对象;
obj.baz();
}
EDIT显然,在依赖类型的上下文中,不允许将解析为void
的内容用作函数参数。我已使用不同的解决方案相应地编辑了我的答案。原始答案如下所示
template<class T>
class Object
{
public:
struct MAKE_ILLEGAL {};
template<class param>
Object(param p) {/*do stuff */}
Object() {/* default */ }
template<bool b>
Object<T> baz(std::conditional_t<b, int, MAKE_ILLEGAL> param)
{ return Object<T>(param); }
template<bool b>
Object<T> baz(std::conditional_t<b, MAKE_ILLEGAL, int> value = 0)
{ return Object<T>(); }
};
int main() {
Object<double> obj;
obj.baz<false>();
}
其思想是创建两个重载,一个用于单个参数,一个用于无。通过有选择地将参数替换为不可访问的伪类型,可以确保在不合适的情况下永远无法调用该重载。EDIT显然,在依赖类型的上下文中,不允许将解析为
void
的内容用作函数参数。我已使用不同的解决方案相应地编辑了我的答案。原始答案如下所示
template<class T>
class Object
{
public:
struct MAKE_ILLEGAL {};
template<class param>
Object(param p) {/*do stuff */}
Object() {/* default */ }
template<bool b>
Object<T> baz(std::conditional_t<b, int, MAKE_ILLEGAL> param)
{ return Object<T>(param); }
template<bool b>
Object<T> baz(std::conditional_t<b, MAKE_ILLEGAL, int> value = 0)
{ return Object<T>(); }
};
int main() {
Object<double> obj;
obj.baz<false>();
}
其思想是创建两个重载,一个用于单个参数,一个用于无。通过有选择地将参数替换为不可访问的伪类型,您可以确保在不合适的情况下永远无法调用该重载。我认为没有比您的解决方案更好的选项(忽略专门化)。另外,您的
IF_ELSE
可以替换为std::conditional
[\t
]。您可以使对象
非模板化,而改为使用模板对象baz(t&…params)
,但我不确定它是否适用于您的设计。您是否可以使用auto f=[]()->void{}然后,您可以使用IF_ELSE=std::conditional\t创建别名:template,而不是模板参数中的void
passdecltype(someFunc())
代码>。那么,你就不需要一直写代码<::类型< /代码>。@ JoeFraseFrimsCube,C++模板元程序中已经建立了名<代码>条件< /代码>。使用不同的名称需要任何阅读代码的人了解这是什么,然后意识到它只是std::conditional
。我认为没有比您的解决方案更好的选项(忽略专门化)。另外,您的IF_ELSE
可以替换为std::conditional
[\t
]。您可以使对象
非模板化,而改为使用模板对象baz(t&…params)
,但我不确定它是否适用于您的设计。您是否可以使用auto f=[]()->void{}然后,您可以使用IF_ELSE=std::conditional\t创建别名:template,而不是模板参数中的void
passdecltype(someFunc())
代码>。那么,你就不需要一直写代码<::类型< /代码>。@ JoeFraseFrimsCube,C++模板元程序中已经建立了名<代码>条件< /代码>。使用不同的名称需要任何阅读代码的人了解这是什么,然后意识到它只是std::conditional
。因此,这不起作用,因为您不能将void用作类型(c++14和c++17中的编译错误)无效的参数类型“std::conditional_t{aka void}
,但您可以。。。。(检查编辑后的答案)我会暂时给你最好的答案,因为我认为这个问题没有实际的解决方案,你给了我灵感,让我找到更干净的解决方法。(:@JosephFranciscus好吧,你可以,但显然不是在依赖类型的上下文中。所以在这种情况下它确实不起作用。这是一个糟糕的问题。但我想我知道另一个技巧,我现在正在摆弄它,我会适当地编辑我的答案。@JosephFranciscus是的,这一次验证;)所以这不起作用,因为您不能使用void作为类型(c++14和c++17中的编译错误)无效的参数类型'std::conditional_t{aka void}
,但您可以这样做。。。。(检查编辑后的答案)我会暂时给你最好的答案,因为我认为这个问题没有实际的解决方案,你给了我灵感,让我找到更干净的解决方法。(:@JosephFranciscus好吧,你可以,但显然不是在依赖类型的上下文中。所以在这种情况下它确实不起作用。这是一个糟糕的问题。但我想我知道另一个技巧,我现在正在摆弄它,我会适当地编辑我的答案。@JosephFranciscus是的,这一次验证;)
template<class T>
class Object
{
public:
struct MAKE_ILLEGAL {};
template<class param>
Object(param p) {/*do stuff */}
Object() {/* default */ }
template<bool b>
Object<T> baz(std::conditional_t<b, int, MAKE_ILLEGAL> param)
{ return Object<T>(param); }
template<bool b>
Object<T> baz(std::conditional_t<b, MAKE_ILLEGAL, int> value = 0)
{ return Object<T>(); }
};
int main() {
Object<double> obj;
obj.baz<false>();
}
// A helper that always yields true so we can make the condition type-dependent
// on arbitrary template parameters
template<class T>
constexpr bool true_v = true;
template<class T>
class Object
{
public:
template<class U = void, std::enable_if_t<Condition<T>::value && true_v<U>, int> = 0>
Object baz(foo_class param)
{ return Object(param); }
template<class U = void, std::enable_if_t<!Condition<T>::value && true_v<U>, int> = 0>
Object baz()
{ return Object(); }
};
template<class T>
class Object
{
private:
struct dummy { };
public:
Object baz(std::conditional_t<Conditional<T>::value, foo_class, dummy> param)
{ return Object(param); }
Object baz(std::conditional_t<Conditional<T>::value, dummy, void>)
{ return Object(); }
};