考虑下一个例子:
#include <iostream>
template< int a >
void foo();
int main(int argn, char* argv[])
{
foo<1>();
}
template<>
void foo<1>()
{
std::cout<<1<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
编译失败,出现下一条错误消息:
rg.cpp:12: error: specialization of ‘void foo() [with int a = 1]’ after instantiation
Run Code Online (Sandbox Code Playgroud)
标准中的哪一段解释了这个错误?
PS:我知道如果我在main前面移动函数定义会使错误消失.
从一些关于模板专业化的幻灯片:
#include <iostream>
using namespace std;
template<class X>
X& min(X& a, X& b)
{
return a > b ? b : a;
}
int& min(int& a, int & b)
{
// rewrite of the function in the case of int:
cout << "int explicit function\n";
return a > b ? b : a;
}
/*
new syntax – the more appropriate way:
template<>
int& min<int>(int& a, int& b)
{
cout << "int explicit function\n";
return a > b ? b …Run Code Online (Sandbox Code Playgroud) 以下代码在Visual C++ 2013中编译,但不在G ++ 4.8.2下编译:
template<class T>
int MyFunc(T& t)
{
return static_cast<int>(CCodes::blah);
}
template<>
int MyFunc(float& t)
{
return 0;
}
int main() {
float f = 10.f;
return MyFunc(f);
}
Run Code Online (Sandbox Code Playgroud)
Visual C++似乎忽略了通用模板函数,因为只MyFunc<float>使用了特化.无论如何,G ++解析了一般函数,并发现尚未定义CCodes枚举.
哪个是对的?或者是这个实现定义的?
我有以下模板类和模板函数,它们打算访问类的私有数据成员:
#include <iostream>
template<class T>
class MyVar
{
int x;
};
template<class T>
void printVar(const MyVar<T>& var)
{
std::cout << var.x << std::endl;
}
template<class T>
void scanVar(MyVar<T>& var)
{
std::cin >> var.x;
}
struct Foo {};
int main(void)
{
MyVar<Foo> a;
scanVar(a);
printVar(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为了将这两个函数声明为MyVar<T>友元函数,我在声明中尝试了以下方法template<class T> class MyVar来声明友元。它们都不起作用。我应该怎么做?
template<class T> friend void printVar(const MyVar&);
template<class T> friend void scanVar(MyVar&);
// compilation error
template<class T> friend void printVar(const MyVar<T>&);
template<class T> friend void scanVar(MyVar<T>&); …Run Code Online (Sandbox Code Playgroud) 我的程序的目的是创建一个数据列表,我可以在类层次结构中使用静态多态性时通过一组静态访问者访问该数据列表。
我通过 CRTP 利用静态多态性创建了一个类层次结构:
class VirtualBaseData {
public:
//someVirtualFunction
}
template<typename Derived>
class BaseData<Derived> {
public:
template<typename Visitor>
void accept(Visitor &v){
static_cast<Derived*>(this)->accept(v);
}
}
class DerivedBaseData1: BaseData<DerivedBaseData> {
public:
template<typename Visitor>
void accept(Visitor &v){
//Specific implementation
}
}
class DerivedBaseData2: BaseData<DerivedBaseData> {
public:
template<typename Visitor>
void accept(Visitor &v){
//Specific implementation
}
}
Run Code Online (Sandbox Code Playgroud)
我想将 DerivedBaseData 存储在一个容器中,以便稍后进行迭代和访问。
int main(){
std::vector<VirtualBaseData*> dataSet;
dataSet.push_back(new DerivedBaseData1);
dataSet.push_back(new DerivedBaseData2);
for(auto it = fifth.begin(); it != fifth.end(); ++it){
it->accept(); //Error: VirtualBaseData does not have a member function …Run Code Online (Sandbox Code Playgroud) c++ crtp static-polymorphism template-function static-visitor
考虑在c ++中实现例程的三种方法:通过仿函数,成员函数和非成员函数.例如,
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
class FOO
{
public:
void operator() (string word) // first: functor
{
cout << word << endl;
}
void m_function(string word) // second: member-function
{
cout << word << endl;
}
} FUNCTOR;
void function(string word) // third: non-member function
{
cout << word << endl;
}
Run Code Online (Sandbox Code Playgroud)
现在考虑一个模板函数来调用上面的三个函数:
template<class T>
void eval(T fun)
{
fun("Using an external function");
}
Run Code Online (Sandbox Code Playgroud)
FOO::m_function通过eval 调用的正确方法是什么?
我试过了:
FUNCTOR("Normal call"); // OK: call …Run Code Online (Sandbox Code Playgroud) c++ templates member-function-pointers functor template-function
在以下情况下选择正确的函数重载的正确方法是什么?
#include <iostream>
#include <algorithm>
/** the correct overload **/
bool predicate( const char& c )
{
return c == '0';
}
/** the wrong overload **/
template< typename CharType >
bool predicate( const CharType& c, int some_other_parameters )
{
return c == '0';
}
std::string
process_string( const std::string& str )
{
std::string result;
std::copy_if( str.begin( ),
str.end( ),
std::back_inserter( result ),
predicate );
return result;
}
int main()
{
std::cout << process_string("AK0NNDK0ASDAS0") << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我希望能够避免在条件为false时调用函数,这在编译时已知.现在我使用这样的东西:
template<bool Enabled>
void fun(params)
{
//do nothing
}
template<>
void fun<true>(params)
{
//do something with params.
}
Run Code Online (Sandbox Code Playgroud)
params即使函数体是空的,我也不喜欢这种方法.
我想要一个解决方案,当根本没有调用该函数时,当条件为假时,不会对params进行求值(这可能在第一种情况下使用空函数进行优化,但我不能认为这是真的.编译器).
这甚至可能吗?
我有以下模板方法:
struct MyStruct
{
// ...
template<typename T>
void readField(std::istream& in, T& data)
{
read(in, data);
data = ntohl(data);
}
};
template<>
void MyStruct::readField<uint8_t>(std::istream& in, uint8_t& data)
{
read(in, data);
}
Run Code Online (Sandbox Code Playgroud)
但是我得到那些奇怪的链接器错误:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/exception:62:`void MyStruct :: readField的多个定义(std :: basic_istream>&,未签名的char&)'../Lib/obj/MyStruct.o:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../。 ./include/c++/4.4.7/exception:62:首先在这里定义collect2:ld返回1退出状态make:*** [lib]错误1
如何专门化该成员函数?
编辑
此方法有效:
struct MyStruct
{
// ...
template<typename T>
void readField(std::istream& in, T& data)
{
read(in, data);
data = ntohl(data);
}
void readField(std::istream& in, uint8_t& data)
{
read(in, data);
}
};
Run Code Online (Sandbox Code Playgroud)
或与inlines或在课外使用inline
struct MyStruct
{
// …Run Code Online (Sandbox Code Playgroud) 好的,所以我有这个模板类,有点像单向列表。
template <typename T> List
Run Code Online (Sandbox Code Playgroud)
它具有此内部功能打印
public:
void Print();
Run Code Online (Sandbox Code Playgroud)
如您所料,它从头到尾打印列表内容;但是,由于模板可以将类视为T,因此可以想象,在这种情况下,我将需要Print()的不同实现。例如,我有另一个班级Point
class Point{
private:
int x, y;
public:
int getX();
int getY();
}
Run Code Online (Sandbox Code Playgroud)
所以我要专门为积分设计打印。我尝试了这个:
void List<Point>::Print();
Run Code Online (Sandbox Code Playgroud)
但是编译器告诉我
prototype for void List<Point> Print() doesn match any in class List<Point>
Run Code Online (Sandbox Code Playgroud)
虽然
candidates are: from List<T> [with T = Point] void List<Point>::Print()
Run Code Online (Sandbox Code Playgroud)
对我来说,这似乎是一样的功能。怎么了?以及如何编写T特定的模板类函数?
c++ ×10
templates ×5
c++11 ×2
overloading ×2
class ×1
compiler-bug ×1
crtp ×1
friend ×1
functor ×1
static-if ×1