所以我有一个模板化的类,当我有特定的类型时,我想重载一个函数的行为,比如说char.对于所有其他类型,让他们做自己的事情.但是,c ++不会让我重载该函数.
为什么我不能重载这个功能?我真的不想做模板专业化,因为那时我已经复制了整个班级.
这是一个展示问题的玩具示例:http://codepad.org/eTgLG932
这里贴出相同的代码供您阅读:
#include <iostream>
#include <cstdlib>
#include <string>
struct Bar
{
std::string blah() { return "blah"; }
};
template <typename T>
struct Foo
{
public:
std::string doX()
{
return m_getY(my_t);
}
private:
std::string m_getY(char* p_msg)
{
return std::string(p_msg);
}
std::string m_getY(T* p_msg)
{
return p_msg->blah();
}
T my_t;
};
int main(int, char**)
{
Foo<char> x;
Foo<Bar> y;
std::cout << "x " << x.doX() << std::endl;
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
谢谢大家的建议.提出了两种有效的解决方案.我可以专门化doX方法,或者专门化m_getY()方法.
在一天结束时,我宁愿保持我的专业而不是公开,所以我接受了Krill的回答.
我深入研究了一个新项目,我用一堆模板和专业知识来解决这个问题.现在,在没有编程的一天之后,我发现自己在询问是否真的值得额外的代码行.
问题是:专业化有哪些优势?
这是:
template <int i> class A {};
template <> class A <1> { void foo() {/* something */} };
template <> class A <2> { void foo() {/* something else*/} };
template <> class A <3> { void foo() {/* even different*/} };
Run Code Online (Sandbox Code Playgroud)
以任何方式更好(更快的执行)
template <int i> class A {
void foo() {
if (i==1) {/* something */}
else if (i==2) {/* something else*/}
else if (i==3) {/* even different*/}
}
};
Run Code Online (Sandbox Code Playgroud)
?
编辑:
该代码是其他人使用的库的一部分.我正在使用gcc 4.6.3但最终代码将与不同的编译器一起使用.
编辑:
这两段代码使用gcc …
我试图专门化一些几何函数,取决于2D或3D,由模板参数指定.如果我为问题的玩具版本包含一些(非常破碎的)代码,那么最好:
template <typename T, int d>
class Point
{
public:
int x;
int y;
int z;
T add ()
{
return T(0);
}
template <>
T add <T, 2> ()
{
return x + y;
}
template <>
T add <T, 3> ()
{
return x + y + z;
}
};
Run Code Online (Sandbox Code Playgroud)
这段代码很难编译.我已经尝试了很多模板参数格式和类定义的不同组合,并且在'd'上找不到一种方法来执行函数特化,同时保留'T'一般.
在我的实际解决方案中,我正在尝试计算专门用于2D或3D情况的渐变,曲率,插值等内容.有些事情,比如梯度计算,可以简单地使用'd'参数来限制for循环迭代.其他如插值,需要单独的2D和3D功能.
任何提示非常感谢!
我基本上试图做一个模板化专业化中讨论的内容,这个模板专门化来自模板化的类,除了我的TClass有多个模板参数,如下所示:
template < class KEY, class TYPE >
class TClass
{
public:
:
void doSomething(KEY * v);
:
};
template < class KEY, class TYPE >
void TClass<KEY, TYPE>::doSomething(KEY * v)
{
// do something
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,这是有效的,但我如何为一个模板参数定义一个专门的实现?我尝试添加这个:
template < class TYPE >
void TClass<int, TYPE>::doSomething(int * v)
{
// do something if KEY is int
}
Run Code Online (Sandbox Code Playgroud)
但是编译器抱怨"无法将函数定义与现有声明匹配"(VC2010)用于该方法/函数.
作为旁注:如果我同时专门化两个模板参数,它可以工作:
template < >
void TClass<int, char>::doSomething(int * v)
{
// do something if KEY is int and TYPE …Run Code Online (Sandbox Code Playgroud) 我有一个std::vector<bool>实例(foo比方说),我需要编写一个函数,true如果所有元素都返回true.
我用
return *std::min_element(foo.begin(), foo.end());
Run Code Online (Sandbox Code Playgroud)
实现这一点,但这让我想到:false如果容器包含至少一个false值,你知道最小元素.换句话说,您不需要遍历整个容器end(),这意味着专业化std::min_element是合适的,就像专业化std::vector<bool>被认为是合适的.
我错过了什么吗?或者这会被视为过早的优化?也许一个好的编译器无论如何都会解决它.
让函数 foo 带有以下“签名”:
template<typename ...Ts>
void foo(Ts ...args)
Run Code Online (Sandbox Code Playgroud)
这有点过头了,因为我只需要 foo 来处理doubles。如何修改 foo 使其double仅接受s ?
#include <tuple>
#include <iostream>
template<typename ...Ts>
void foo(Ts ...args)
{
std::tuple<Ts...> tu(args...);
std::apply([](Ts const&... tupleArgs)
{
((std::cout << tupleArgs << " "), ...);
}, tu);
}
int main()
{
foo(-2.44, -5.66, 78.99);
}
Run Code Online (Sandbox Code Playgroud)
输出如下:
-2.44 -5.66 78.99
这是一个最小的代码示例,展示了我正在尝试的工作原理,但不是我希望的工作方式:
#include <string>
#include <type_traits>
#include <iostream>
struct string_tag {
using R=const std::string;
};
struct int_tag {
using R=const int;
};
template <bool TS>
class Wibble {
public:
template<typename TAG>
typename TAG::R getValue(TAG);
};
template <bool TS>
template <typename TAG>
typename TAG::R Wibble<TS>::getValue(TAG) {
if constexpr (std::is_same<TAG, string_tag>::value) {
return "hello";
}
if constexpr (std::is_same<TAG, int_tag>::value) {
return 42;
}
}
// instantiate classes
template class Wibble<true>;
template class Wibble<false>;
int main () {
Wibble<true> tw;
Wibble<false> fw;
std::cout << …Run Code Online (Sandbox Code Playgroud) c++ templates specialization template-specialization function-templates
我试图将一个函数声明为具有受保护成员的类模板的友元。下面是一个最小的例子。
template<int N> class myClass{
public:
friend void f(const myClass& c);
protected:
int a;
};
Run Code Online (Sandbox Code Playgroud)
如果我现在将函数定义为
template<int N> void f(const myClass<N>& c){
std::cout << c.a;
};
Run Code Online (Sandbox Code Playgroud)
然后就可以了。
但是如果我使用模板专业化
template<int N> void f(const myClass<N>& c);
template<> void f<1>(const myClass<1>& c){
std::cout << c.a;
};
Run Code Online (Sandbox Code Playgroud)
它不再承认f自己是朋友,并抱怨说自己a是受保护的成员。
为什么会发生这种情况?我究竟做错了什么?
假设我有
class A {};
template<typename T, typename U> class Wrapper {};
Run Code Online (Sandbox Code Playgroud)
我正在尝试检查包装器的第一个内部类型是否为A.
typeCheck(new A(), new Wrapper<A,B>); // expect true
typeCheck(new A(), new Wrapper<C,B>); // expect false
Run Code Online (Sandbox Code Playgroud)
最好的方法是什么?
我尝试过模板部分专业化,但没有运气。
这是我尝试过的代码:
template<typename T> struct get_inner {
using type = T;
}
template<typename T, typename U>
struct get_inner<Wrapper<T,U>> {
using type = T;
}
std::cout<< typeid(get_inner<decltype(new Wrapper<A,B>)>::type);
Run Code Online (Sandbox Code Playgroud)
控制台显示相同的包装类型而不是内部类型A。这里有什么错误吗?
标头中cnvt.h有:
template <typename t_to, typename t_from> std::optional<t_to> cnvt(t_from);
Run Code Online (Sandbox Code Playgroud)
在 header 中int.h,我们有:
#include "cnvt.h"
template <>
std::optional<uint8_t> cnvt<uint8_t, const char *>(const char *) {
// actual code replaced for simplicity
return {};
}
Run Code Online (Sandbox Code Playgroud)
clang-tidy报道称,事实如此
clang 报告“int.h:: 不直接使用包含的标头 cvnt.h(可用修复) 不直接使用包含的标头 cvnt.h(可用修复)
如果删除#include "cnvt.h",它会报告
int.h:9:24:没有函数模板与函数模板专业化“cnvt”匹配
我搜索了 StackOverflow,关于函数模板专业化的帖子没有帮助。
c++ ×10
specialization ×10
templates ×8
algorithm ×1
boolean ×1
c++20 ×1
class ×1
friend ×1
function ×1
inheritance ×1
type-traits ×1
typechecking ×1
vector ×1