C++ 如何在模板类中别名模板函数
我需要在一个模板类中实现两个函数,这两个函数做相似的事情,但不是所有的事情都是一样的。我建议的解决方案是在单个模板函数上使用C++ 如何在模板类中别名模板函数,c++,c++17,C++,C++17,我需要在一个模板类中实现两个函数,这两个函数做相似的事情,但不是所有的事情都是一样的。我建议的解决方案是在单个模板函数上使用if constexpr,然后为每个函数使用别名: template <typename T> class MyClass { private: template <bool test> void TestFunc() { if constexpr(test) { // Do somethi
if constexpr
,然后为每个函数使用别名:
template <typename T>
class MyClass
{
private:
template <bool test>
void TestFunc()
{
if constexpr(test)
{
// Do something
}
else
{
// Do other stuff
}
}
public:
?????? TestTrue = TestFunc<true>;
?????? TestFalse = TestFunc<false>;
}
模板
类MyClass
{
私人:
模板
void TestFunc()
{
if constexpr(测试)
{
//做点什么
}
其他的
{
//做其他事情
}
}
公众:
???????TestTrue=TestFunc;
???????TestFalse=TestFunc;
}
我正在试图找出问号所在的位置应该是什么,到目前为止,使用
,自动
和常量自动
都不起作用。我希望用户能够直接从类的对象调用TestTrue()
和TestFalse()
。您可以:
void TestTrue() { TestFunc<true>(); }
void TestFalse() { TestFunc<false>(); }
void TestTrue(){TestFunc();}
void TestFalse(){TestFunc();}
我认为没有更好的办法了。你可以:
void TestTrue() { TestFunc<true>(); }
void TestFalse() { TestFunc<false>(); }
void TestTrue(){TestFunc();}
void TestFalse(){TestFunc();}
我认为没有更好的方法了。为了完整起见,这里有一个丑陋的方法 如注释中所述,
TestFunc
是一个成员函数,而不是一个类型,因此如果您想引用它的显式专门化,则需要使用一个。在我们的例子中,这些将是以下类型的指针
using MemberTestFunction = void (MyClass::*)();
然后,我们可以获取指向TestFunc
的true
和false
专门化的指针,如下所示:
template <typename T>
class MyClass
{
// ...
constexpr static MemberTestFunction TestTrue = &MyClass::TestFunc<true>;
constexpr static MemberTestFunction TestFalse = &MyClass::TestFunc<false>;
};
或者,在MyClass
之外,这些调用如下所示
MyClass<nullptr_t> x;
// Using type deducation.
(x.*decltype(x)::TestTrue)();
// Using fully qualified name.
(x.*MyClass<nullptr_t>::TestTrue)();
// Using std::invoke (with type deducation).
std::invoke(decltype(x)::TestTrue, x);
MyClass x;
//使用类型推断。
(x.*decltype(x)::TestTrue)();
//使用完全限定名。
(x.*MyClass::TestTrue)();
//使用std::invoke(带有类型推断)。
调用(decltype(x)::TestTrue,x);
不用说,这是完成任何其他简单任务的一种不必要的模糊方式。我不主张使用这种技术而不是创建新函数(正如HolyBlackCat所建议的那样),或者只是在调用站点显式地命名
TestFunc()
和TestFunc()
。为了完整性,下面是一种丑陋的方式
如注释中所述,TestFunc
是一个成员函数,而不是一个类型,因此如果您想引用它的显式专门化,则需要使用一个。在我们的例子中,这些将是以下类型的指针
using MemberTestFunction = void (MyClass::*)();
然后,我们可以获取指向TestFunc
的true
和false
专门化的指针,如下所示:
template <typename T>
class MyClass
{
// ...
constexpr static MemberTestFunction TestTrue = &MyClass::TestFunc<true>;
constexpr static MemberTestFunction TestFalse = &MyClass::TestFunc<false>;
};
或者,在MyClass
之外,这些调用如下所示
MyClass<nullptr_t> x;
// Using type deducation.
(x.*decltype(x)::TestTrue)();
// Using fully qualified name.
(x.*MyClass<nullptr_t>::TestTrue)();
// Using std::invoke (with type deducation).
std::invoke(decltype(x)::TestTrue, x);
MyClass x;
//使用类型推断。
(x.*decltype(x)::TestTrue)();
//使用完全限定名。
(x.*MyClass::TestTrue)();
//使用std::invoke(带有类型推断)。
调用(decltype(x)::TestTrue,x);
不用说,这是完成任何其他简单任务的一种不必要的模糊方式。我不主张使用这种技术来创建新函数(正如HolyBlackCat建议的那样),也不主张在调用站点显式地命名
TestFunc()
和TestFunc()
。将函数TestFunc
转换为functor:
#include <iostream>
template <typename T>
class MyClass
{
private:
template <bool test>
struct TestFunc
{
void operator()() {
if constexpr(test)
{
std::cout << "TestTrue\n";
}
else
{
std::cout << "TestFalse\n";
}
}
};
public:
TestFunc<true> TestTrue;
TestFunc<false> TestFalse;
};
int main()
{
MyClass<int> myClass;
myClass.TestTrue();
myClass.TestFalse();
}
#包括
模板
类MyClass
{
私人:
模板
结构TestFunc
{
void运算符()(){
if constexpr(测试)
{
std::cout将函数TestFunc
转换为函子:
#include <iostream>
template <typename T>
class MyClass
{
private:
template <bool test>
struct TestFunc
{
void operator()() {
if constexpr(test)
{
std::cout << "TestTrue\n";
}
else
{
std::cout << "TestFalse\n";
}
}
};
public:
TestFunc<true> TestTrue;
TestFunc<false> TestFalse;
};
int main()
{
MyClass<int> myClass;
myClass.TestTrue();
myClass.TestFalse();
}
#包括
模板
类MyClass
{
私人:
模板
结构TestFunc
{
void运算符()(){
if constexpr(测试)
{
std::cout=TestFunc
TestFunc
不是一个类型。您可以创建指向该函数的指针。=TestFunc
TestFunc
不是一个类型。您可以创建指向该函数的指针。我认为您是对的,但有点令人失望:p编译器将内联它。所以这完全是一样的。:)
I我的意思是,是的,但我正在寻找一种漂亮的c++17方法it@cigien也许我下面的答案可以减轻一些失望。我们有工具,它们只是不漂亮:)我想你是对的,但它有点令人失望:p编译器将内联它。所以这完全是一样的。:)
我的意思是,是的,但我正在寻找一个漂亮的c++17方法it@cigien也许我下面的回答可以减轻一些失望。我们有工具,它们只是不漂亮:)我试图尽量减少从类外调用函数的人的头痛…@EyalK.头痛?如果在实际项目中使用,这会让我头痛!我添加了一个简短的免责声明,以澄清我不是sugg与简单的解决方案相比,“测试一个”使用了这一点。使用简洁的抽象仅仅因为你能做到这一点是肯定的。我试图减少从类外调用函数的人的头痛…@EyalK.heading?如果在实际项目中使用,这会让我感到偏头痛!我添加了一个简短的免责声明,以澄清我不是在建议一个通过一个更简单的解决方案来解决这个问题。简单地使用一个简洁的抽象,因为你可以做到这一点是肯定的。